Fix an infinite loop in InstCombine when an instruction with no users and side effect...
authorOwen Anderson <resistor@mac.com>
Tue, 10 Mar 2015 05:13:47 +0000 (05:13 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 10 Mar 2015 05:13:47 +0000 (05:13 +0000)
ReplaceInstUsesWith needs to return nullptr when the input has no users,
because in that case it does not mutate the program.  Otherwise, we can
get stuck in an infinite loop of repeatedly attempting to constant fold
and instruction with no users.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231755 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineInternal.h
test/Transforms/InstCombine/constant-fold-hang.ll [new file with mode: 0644]

index 8c784ab1e682c805fd3f1df53f50de5f29bec71b..fb2321df2e04a2f9d200d91305f8354403a162fa 100644 (file)
@@ -372,6 +372,10 @@ public:
   /// I to the worklist, replace all uses of I with the new value, then return
   /// I, so that the inst combiner will know that I was modified.
   Instruction *ReplaceInstUsesWith(Instruction &I, Value *V) {
+    // If there are no uses to replace, then we return nullptr to indicate that
+    // no changes were made to the program.
+    if (I.use_empty()) return nullptr;
+
     Worklist.AddUsersToWorkList(I); // Add all modified instrs to worklist.
 
     // If we are replacing the instruction with itself, this must be in a
diff --git a/test/Transforms/InstCombine/constant-fold-hang.ll b/test/Transforms/InstCombine/constant-fold-hang.ll
new file mode 100644 (file)
index 0000000..2ca6b86
--- /dev/null
@@ -0,0 +1,14 @@
+; RUN: opt -instcombine < %s
+
+; Function Attrs: nounwind readnone ssp
+define void @mulByZero(<4 x i16> %x) #0 {
+entry:
+  %a = tail call <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16> %x, <4 x i16> zeroinitializer) #2
+  ret void
+}
+
+; Function Attrs: nounwind readnone
+declare <4 x i32> @llvm.arm.neon.vmulls.v4i32(<4 x i16>, <4 x i16>) #1
+
+attributes #0 = { nounwind readnone ssp }
+attributes #1 = { nounwind readnone }