LoopRotate: Don't walk the uses of a Constant
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 27 Jan 2015 06:21:43 +0000 (06:21 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 27 Jan 2015 06:21:43 +0000 (06:21 +0000)
LoopRotate wanted to avoid live range interference by looking at the
uses of a Value in the loop latch and seeing if any lied outside of the
loop.  We would wrongly perform this operation on Constants.

This fixes PR22337.

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

lib/Transforms/Scalar/LoopRotation.cpp
test/Transforms/LoopRotate/pr22337.ll [new file with mode: 0644]

index c37cd917ad2a00386414df0a43198e7d7bd35913..02fb80c0cd54a991820d6cc4d6e178b1010b50e8 100644 (file)
@@ -229,20 +229,17 @@ static bool shouldSpeculateInstrs(BasicBlock::iterator Begin,
     case Instruction::Shl:
     case Instruction::LShr:
     case Instruction::AShr: {
-      Value *IVOpnd = nullptr;
-      if (isa<ConstantInt>(I->getOperand(0)))
-        IVOpnd = I->getOperand(1);
-
-      if (isa<ConstantInt>(I->getOperand(1))) {
-        if (IVOpnd)
-          return false;
-
-        IVOpnd = I->getOperand(0);
-      }
+      Value *IVOpnd = !isa<Constant>(I->getOperand(0))
+                          ? I->getOperand(0)
+                          : !isa<Constant>(I->getOperand(1))
+                                ? I->getOperand(1)
+                                : nullptr;
+      if (!IVOpnd)
+        return false;
 
       // If increment operand is used outside of the loop, this speculation
       // could cause extra live range interference.
-      if (MultiExitLoop && IVOpnd) {
+      if (MultiExitLoop) {
         for (User *UseI : IVOpnd->users()) {
           auto *UserInst = cast<Instruction>(UseI);
           if (!L->contains(UserInst))
diff --git a/test/Transforms/LoopRotate/pr22337.ll b/test/Transforms/LoopRotate/pr22337.ll
new file mode 100644 (file)
index 0000000..c2893db
--- /dev/null
@@ -0,0 +1,24 @@
+; RUN: opt < %s -loop-rotate -S | FileCheck %s
+
+@a = external global i8, align 4
+@tmp = global i8* @a
+
+define void @f() {
+; CHECK-LABEL: define void @f(
+; CHECK: getelementptr i8* @a, i32 0
+entry:
+  br label %for.preheader
+
+for.preheader:
+  br i1 undef, label %if.then8, label %for.body
+
+for.body:
+  br i1 undef, label %if.end, label %if.then8
+
+if.end:
+  %arrayidx = getelementptr i8* @a, i32 0
+  br label %for.preheader
+
+if.then8:
+  unreachable
+}