[llvm] r181604 - InstCombine: Don't claim to be able to evaluate any shl in a zexted type.

Benjamin Kramer benny.kra at googlemail.com
Fri May 10 09:26:37 PDT 2013


Author: d0k
Date: Fri May 10 11:26:37 2013
New Revision: 181604

URL: http://llvm.org/viewvc/llvm-project?rev=181604&view=rev
Log:
InstCombine: Don't claim to be able to evaluate any shl in a zexted type.

The shift amount may be larger than the type leading to undefined behavior.
Limit the transform to constant shift amounts. While there update the bits to
clear in the result which may enable additional optimizations.

PR15959.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/cast.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=181604&r1=181603&r2=181604&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri May 10 11:26:37 2013
@@ -677,7 +677,6 @@ static bool CanEvaluateZExtd(Value *V, T
   case Instruction::Add:
   case Instruction::Sub:
   case Instruction::Mul:
-  case Instruction::Shl:
     if (!CanEvaluateZExtd(I->getOperand(0), Ty, BitsToClear) ||
         !CanEvaluateZExtd(I->getOperand(1), Ty, Tmp))
       return false;
@@ -701,6 +700,17 @@ static bool CanEvaluateZExtd(Value *V, T
     // Otherwise, we don't know how to analyze this BitsToClear case yet.
     return false;
 
+  case Instruction::Shl:
+    // We can promote shl(x, cst) if we can promote x.  Since shl overwrites the
+    // upper bits we can reduce BitsToClear by the shift amount.
+    if (ConstantInt *Amt = dyn_cast<ConstantInt>(I->getOperand(1))) {
+      if (!CanEvaluateZExtd(I->getOperand(0), Ty, BitsToClear))
+        return false;
+      uint64_t ShiftAmt = Amt->getZExtValue();
+      BitsToClear = ShiftAmt < BitsToClear ? BitsToClear - ShiftAmt : 0;
+      return true;
+    }
+    return false;
   case Instruction::LShr:
     // We can promote lshr(x, cst) if we can promote x.  This requires the
     // ultimate 'and' to clear out the high zero bits we're clearing out though.

Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=181604&r1=181603&r2=181604&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Fri May 10 11:26:37 2013
@@ -898,3 +898,31 @@ define double @test81(double *%p, float
   %l = load double* %r
   ret double %l
 }
+
+define i64 @test82(i64 %A) nounwind {
+  %B = trunc i64 %A to i32
+  %C = lshr i32 %B, 8
+  %D = shl i32 %C, 9
+  %E = zext i32 %D to i64
+  ret i64 %E
+
+; CHECK: @test82
+; CHECK-NEXT:   [[REG:%[0-9]*]] = shl i64 %A, 1
+; CHECK-NEXT:   %E = and i64 [[REG]], 4294966784
+; CHECK-NEXT:   ret i64 %E
+}
+
+; PR15959
+define i64 @test83(i16 %a, i64 %k) {
+  %conv = sext i16 %a to i32
+  %sub = add nsw i64 %k, -1
+  %sh_prom = trunc i64 %sub to i32
+  %shl = shl i32 %conv, %sh_prom
+  %sh_prom1 = zext i32 %shl to i64
+  ret i64 %sh_prom1
+
+; CHECK: @test83
+; CHECK: %sub = add nsw i64 %k, 4294967295
+; CHECK: %sh_prom = trunc i64 %sub to i32
+; CHECK: %shl = shl i32 %conv, %sh_prom
+}





More information about the llvm-commits mailing list