[llvm-commits] [llvm] r44248 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll

Nick Lewycky nicholas at mxc.ca
Tue Nov 20 00:24:45 PST 2007


Author: nicholas
Date: Tue Nov 20 02:24:44 2007
New Revision: 44248

URL: http://llvm.org/viewvc/llvm-project?rev=44248&view=rev
Log:
Be more careful when transforming | to +. Patch from Wojciech Matyjewicz.

Added:
    llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44248&r1=44247&r2=44248&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 20 02:24:44 2007
@@ -1484,25 +1484,27 @@
     case Instruction::SDiv:
       return SE.getSDivExpr(getSCEV(I->getOperand(0)),
                             getSCEV(I->getOperand(1)));
-      break;
-
     case Instruction::Sub:
       return SE.getMinusSCEV(getSCEV(I->getOperand(0)),
                              getSCEV(I->getOperand(1)));
     case Instruction::Or:
       // If the RHS of the Or is a constant, we may have something like:
-      // X*4+1 which got turned into X*4|1.  Handle this as an add so loop
+      // X*4+1 which got turned into X*4|1.  Handle this as an Add so loop
       // optimizations will transparently handle this case.
+      //
+      // In order for this transformation to be safe, the LHS must be of the
+      // form X*(2^n) and the Or constant must be less than 2^n.
+
       if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
         SCEVHandle LHS = getSCEV(I->getOperand(0));
         APInt CommonFact(GetConstantFactor(LHS));
         assert(!CommonFact.isMinValue() &&
                "Common factor should at least be 1!");
-        if (CommonFact.ugt(CI->getValue())) {
-          // If the LHS is a multiple that is larger than the RHS, use +.
+        const APInt &CIVal = CI->getValue();
+        if (CommonFact.countTrailingZeros() >=
+            (CIVal.getBitWidth() - CIVal.countLeadingZeros()))
           return SE.getAddExpr(LHS,
                                getSCEV(I->getOperand(1)));
-        }
       }
       break;
     case Instruction::Xor:

Added: llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll?rev=44248&view=auto

==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll Tue Nov 20 02:24:44 2007
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | opt -analyze -scalar-evolution 2>&1 | grep -e '-->  %b'
+; PR1810
+
+define void @fun() {
+entry:
+        br label %header
+header:
+        %i = phi i32 [ 1, %entry ], [ %i.next, %body ]
+        %cond = icmp eq i32 %i, 10
+        br i1 %cond, label %exit, label %body
+body:
+        %a = mul i32 %i, 5
+        %b = or i32 %a, 1
+        %i.next = add i32 %i, 1
+        br label %header
+exit:        
+        ret void
+}





More information about the llvm-commits mailing list