[llvm] a6df392 - [InstSimplify] Fold out-of-bounds shift to poison

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 6 11:41:55 PST 2021


Author: Nikita Popov
Date: 2021-01-06T20:41:37+01:00
New Revision: a6df39236fdc6e422f6794935e5e08e05f566e23

URL: https://github.com/llvm/llvm-project/commit/a6df39236fdc6e422f6794935e5e08e05f566e23
DIFF: https://github.com/llvm/llvm-project/commit/a6df39236fdc6e422f6794935e5e08e05f566e23.diff

LOG: [InstSimplify] Fold out-of-bounds shift to poison

Make InstSimplify return poison rather than undef for out-of-bounds
shifts, as specified by LandRef:

> If op2 is (statically or dynamically) equal to or larger than the
> number of bits in op1, this instruction returns a poison value.

Differential Revision: https://reviews.llvm.org/D93998

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstCombine/add-shl-sdiv-to-srem.ll
    llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll
    llvm/test/Transforms/InstCombine/phi-shifts.ll
    llvm/test/Transforms/InstCombine/shift.ll
    llvm/test/Transforms/InstSimplify/shift-knownbits.ll
    llvm/test/Transforms/InstSimplify/shift.ll
    llvm/test/Transforms/InstSimplify/undef.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 659b71fae6a0..1304f0e78b29 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1197,13 +1197,13 @@ Value *llvm::SimplifyURemInst(Value *Op0, Value *Op1, const SimplifyQuery &Q) {
   return ::SimplifyURemInst(Op0, Op1, Q, RecursionLimit);
 }
 
-/// Returns true if a shift by \c Amount always yields undef.
-static bool isUndefShift(Value *Amount, const SimplifyQuery &Q) {
+/// Returns true if a shift by \c Amount always yields poison.
+static bool isPoisonShift(Value *Amount, const SimplifyQuery &Q) {
   Constant *C = dyn_cast<Constant>(Amount);
   if (!C)
     return false;
 
-  // X shift by undef -> undef because it may shift by the bitwidth.
+  // X shift by undef -> poison because it may shift by the bitwidth.
   if (Q.isUndefValue(C))
     return true;
 
@@ -1218,7 +1218,7 @@ static bool isUndefShift(Value *Amount, const SimplifyQuery &Q) {
     for (unsigned I = 0,
                   E = cast<FixedVectorType>(C->getType())->getNumElements();
          I != E; ++I)
-      if (!isUndefShift(C->getAggregateElement(I), Q))
+      if (!isPoisonShift(C->getAggregateElement(I), Q))
         return false;
     return true;
   }
@@ -1246,8 +1246,8 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
     return Op0;
 
   // Fold undefined shifts.
-  if (isUndefShift(Op1, Q))
-    return UndefValue::get(Op0->getType());
+  if (isPoisonShift(Op1, Q))
+    return PoisonValue::get(Op0->getType());
 
   // If the operation is with the result of a select instruction, check whether
   // operating on either branch of the select always yields the same value.
@@ -1265,7 +1265,7 @@ static Value *SimplifyShift(Instruction::BinaryOps Opcode, Value *Op0,
   // the number of bits in the type, the shift is undefined.
   KnownBits Known = computeKnownBits(Op1, Q.DL, 0, Q.AC, Q.CxtI, Q.DT);
   if (Known.One.getLimitedValue() >= Known.getBitWidth())
-    return UndefValue::get(Op0->getType());
+    return PoisonValue::get(Op0->getType());
 
   // If all valid bits in the shift amount are known zero, the first operand is
   // unchanged.

diff  --git a/llvm/test/Transforms/InstCombine/add-shl-sdiv-to-srem.ll b/llvm/test/Transforms/InstCombine/add-shl-sdiv-to-srem.ll
index 1dee5eb90ea1..3157cde6d95f 100644
--- a/llvm/test/Transforms/InstCombine/add-shl-sdiv-to-srem.ll
+++ b/llvm/test/Transforms/InstCombine/add-shl-sdiv-to-srem.ll
@@ -200,7 +200,7 @@ define <3 x i8> @add-shl-sdiv-negative3(<3 x i8> %x) {
 
 define <2 x i64> @add-shl-sdiv-negative4(<2 x i64> %x) {
 ; CHECK-LABEL: @add-shl-sdiv-negative4(
-; CHECK-NEXT:    ret <2 x i64> undef
+; CHECK-NEXT:    ret <2 x i64> poison
 ;
   %sd = sdiv <2 x i64> %x, <i64 32, i64 32>
   %sl = shl <2 x i64> %sd, <i64 -5, i64 -5>

diff  --git a/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll b/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll
index f3b95ed07d44..269e795d8f23 100644
--- a/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll
+++ b/llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll
@@ -6,7 +6,7 @@ define i32 @test_out_of_bounds(i32 %a, i1 %x, i1 %y) {
 ; CHECK-LABEL: @test_out_of_bounds(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A:%.*]], 3
-; CHECK-NEXT:    tail call void @llvm.assume(i1 undef)
+; CHECK-NEXT:    tail call void @llvm.assume(i1 poison)
 ; CHECK-NEXT:    ret i32 [[AND1]]
 ;
 entry:
@@ -20,7 +20,7 @@ entry:
 define i128 @test_non64bit(i128 %a) {
 ; CHECK-LABEL: @test_non64bit(
 ; CHECK-NEXT:    [[AND1:%.*]] = and i128 [[A:%.*]], 3
-; CHECK-NEXT:    tail call void @llvm.assume(i1 undef)
+; CHECK-NEXT:    tail call void @llvm.assume(i1 poison)
 ; CHECK-NEXT:    ret i128 [[AND1]]
 ;
   %and1 = and i128 %a, 3

diff  --git a/llvm/test/Transforms/InstCombine/phi-shifts.ll b/llvm/test/Transforms/InstCombine/phi-shifts.ll
index 732d4aee350b..e109f38b2b83 100644
--- a/llvm/test/Transforms/InstCombine/phi-shifts.ll
+++ b/llvm/test/Transforms/InstCombine/phi-shifts.ll
@@ -9,7 +9,7 @@ define i64 @fuzz15217(i1 %cond, i8* %Ptr, i64 %Val) {
 ; CHECK:       two:
 ; CHECK-NEXT:    br label [[END]]
 ; CHECK:       end:
-; CHECK-NEXT:    ret i64 undef
+; CHECK-NEXT:    ret i64 poison
 ;
 entry:
   br i1 %cond, label %end, label %two

diff  --git a/llvm/test/Transforms/InstCombine/shift.ll b/llvm/test/Transforms/InstCombine/shift.ll
index 6d9d74fd8199..61cbec61bba4 100644
--- a/llvm/test/Transforms/InstCombine/shift.ll
+++ b/llvm/test/Transforms/InstCombine/shift.ll
@@ -1209,7 +1209,7 @@ bb12:                                             ; preds = %bb11, %bb8, %bb
 
 define i32 @test62(i32 %a) {
 ; CHECK-LABEL: @test62(
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 poison
 ;
   %b = ashr i32 %a, 32  ; shift all bits out
   ret i32 %b
@@ -1217,7 +1217,7 @@ define i32 @test62(i32 %a) {
 
 define <4 x i32> @test62_splat_vector(<4 x i32> %a) {
 ; CHECK-LABEL: @test62_splat_vector(
-; CHECK-NEXT:    ret <4 x i32> undef
+; CHECK-NEXT:    ret <4 x i32> poison
 ;
   %b = ashr <4 x i32> %a, <i32 32, i32 32, i32 32, i32 32>  ; shift all bits out
   ret <4 x i32> %b
@@ -1720,7 +1720,6 @@ define i177 @lshr_out_of_range(i177 %Y, i177** %A2) {
 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26716
 define i177 @lshr_out_of_range2(i177 %Y, i177** %A2) {
 ; CHECK-LABEL: @lshr_out_of_range2(
-; CHECK-NEXT:    store i177** [[A2:%.*]], i177*** undef, align 8
 ; CHECK-NEXT:    ret i177 0
 ;
   %B5 = udiv i177 %Y, -1

diff  --git a/llvm/test/Transforms/InstSimplify/shift-knownbits.ll b/llvm/test/Transforms/InstSimplify/shift-knownbits.ll
index c023048fb538..e7302b66ea8a 100644
--- a/llvm/test/Transforms/InstSimplify/shift-knownbits.ll
+++ b/llvm/test/Transforms/InstSimplify/shift-knownbits.ll
@@ -6,7 +6,7 @@
 
 define i32 @shl_amount_is_known_bogus(i32 %a, i32 %b) {
 ; CHECK-LABEL: @shl_amount_is_known_bogus(
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 poison
 ;
   %or = or i32 %b, 32
   %shl = shl i32 %a, %or
@@ -17,7 +17,7 @@ define i32 @shl_amount_is_known_bogus(i32 %a, i32 %b) {
 
 define i31 @lshr_amount_is_known_bogus(i31 %a, i31 %b) {
 ; CHECK-LABEL: @lshr_amount_is_known_bogus(
-; CHECK-NEXT:    ret i31 undef
+; CHECK-NEXT:    ret i31 poison
 ;
   %or = or i31 %b, 31
   %shr = lshr i31 %a, %or
@@ -26,7 +26,7 @@ define i31 @lshr_amount_is_known_bogus(i31 %a, i31 %b) {
 
 define i33 @ashr_amount_is_known_bogus(i33 %a, i33 %b) {
 ; CHECK-LABEL: @ashr_amount_is_known_bogus(
-; CHECK-NEXT:    ret i33 undef
+; CHECK-NEXT:    ret i33 poison
 ;
   %or = or i33 %b, 33
   %shr = ashr i33 %a, %or
@@ -84,7 +84,7 @@ define i9 @shl_amount_is_not_known_zero(i9 %a, i9 %b) {
 
 define <2 x i32> @ashr_vector_bogus(<2 x i32> %a, <2 x i32> %b) {
 ; CHECK-LABEL: @ashr_vector_bogus(
-; CHECK-NEXT:    ret <2 x i32> undef
+; CHECK-NEXT:    ret <2 x i32> poison
 ;
   %or = or <2 x i32> %b, <i32 32, i32 32>
   %shr = ashr <2 x i32> %a, %or

diff  --git a/llvm/test/Transforms/InstSimplify/shift.ll b/llvm/test/Transforms/InstSimplify/shift.ll
index 87b14e1af568..88107e9f1518 100644
--- a/llvm/test/Transforms/InstSimplify/shift.ll
+++ b/llvm/test/Transforms/InstSimplify/shift.ll
@@ -51,7 +51,7 @@ define <2 x i141> @ashr_0_vec_undef_elt(<2 x i141> %X) {
 
 define i55 @lshr_by_bitwidth(i55 %A) {
 ; CHECK-LABEL: @lshr_by_bitwidth(
-; CHECK-NEXT:    ret i55 undef
+; CHECK-NEXT:    ret i55 poison
 ;
   %B = lshr i55 %A, 55
   ret i55 %B
@@ -59,7 +59,7 @@ define i55 @lshr_by_bitwidth(i55 %A) {
 
 define i32 @shl_by_bitwidth(i32 %A) {
 ; CHECK-LABEL: @shl_by_bitwidth(
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 poison
 ;
   %B = shl i32 %A, 32
   ret i32 %B
@@ -67,7 +67,7 @@ define i32 @shl_by_bitwidth(i32 %A) {
 
 define <4 x i32> @lshr_by_bitwidth_splat(<4 x i32> %A) {
 ; CHECK-LABEL: @lshr_by_bitwidth_splat(
-; CHECK-NEXT:    ret <4 x i32> undef
+; CHECK-NEXT:    ret <4 x i32> poison
 ;
   %B = lshr <4 x i32> %A, <i32 32, i32 32, i32 32, i32 32>     ;; shift all bits out
   ret <4 x i32> %B
@@ -83,7 +83,7 @@ define <4 x i32> @lshr_by_0_splat(<4 x i32> %A) {
 
 define <4 x i32> @shl_by_bitwidth_splat(<4 x i32> %A) {
 ; CHECK-LABEL: @shl_by_bitwidth_splat(
-; CHECK-NEXT:    ret <4 x i32> undef
+; CHECK-NEXT:    ret <4 x i32> poison
 ;
   %B = shl <4 x i32> %A, <i32 32, i32 32, i32 32, i32 32>     ;; shift all bits out
   ret <4 x i32> %B
@@ -238,11 +238,9 @@ define <2 x i64> @shl_or_shr2v(<2 x i32> %a, <2 x i32> %b) {
   ret <2 x i64> %tmp5
 }
 
-; TOOD: these should be poison
-
 define i32 @poison(i32 %x) {
 ; CHECK-LABEL: @poison(
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 poison
 ;
   %v = lshr i32 %x, poison
   ret i32 %v
@@ -250,7 +248,7 @@ define i32 @poison(i32 %x) {
 
 define i32 @poison2(i32 %x) {
 ; CHECK-LABEL: @poison2(
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 poison
 ;
   %v = ashr i32 %x, poison
   ret i32 %v
@@ -258,12 +256,14 @@ define i32 @poison2(i32 %x) {
 
 define i32 @poison3(i32 %x) {
 ; CHECK-LABEL: @poison3(
-; CHECK-NEXT:    ret i32 undef
+; CHECK-NEXT:    ret i32 poison
 ;
   %v = shl i32 %x, poison
   ret i32 %v
 }
 
+; TODO: these should be poison
+
 define i32 @poison4(i32 %x) {
 ; CHECK-LABEL: @poison4(
 ; CHECK-NEXT:    ret i32 0

diff  --git a/llvm/test/Transforms/InstSimplify/undef.ll b/llvm/test/Transforms/InstSimplify/undef.ll
index 024ef15d31e1..fe40f2ce319e 100644
--- a/llvm/test/Transforms/InstSimplify/undef.ll
+++ b/llvm/test/Transforms/InstSimplify/undef.ll
@@ -99,7 +99,7 @@ define i64 @test11() {
 
 define i64 @test11b(i64 %a) {
 ; CHECK-LABEL: @test11b(
-; CHECK-NEXT:    ret i64 undef
+; CHECK-NEXT:    ret i64 poison
 ;
   %r = shl i64 %a, undef
   ret i64 %r
@@ -115,7 +115,7 @@ define i64 @test12() {
 
 define i64 @test12b(i64 %a) {
 ; CHECK-LABEL: @test12b(
-; CHECK-NEXT:    ret i64 undef
+; CHECK-NEXT:    ret i64 poison
 ;
   %r = ashr i64 %a, undef
   ret i64 %r
@@ -131,7 +131,7 @@ define i64 @test13() {
 
 define i64 @test13b(i64 %a) {
 ; CHECK-LABEL: @test13b(
-; CHECK-NEXT:    ret i64 undef
+; CHECK-NEXT:    ret i64 poison
 ;
   %r = lshr i64 %a, undef
   ret i64 %r
@@ -180,7 +180,7 @@ define i64 @test18(i64 %a) {
 
 define <4 x i8> @test19(<4 x i8> %a) {
 ; CHECK-LABEL: @test19(
-; CHECK-NEXT:    ret <4 x i8> undef
+; CHECK-NEXT:    ret <4 x i8> poison
 ;
   %b = shl <4 x i8> %a, <i8 8, i8 9, i8 undef, i8 -1>
   ret <4 x i8> %b


        


More information about the llvm-commits mailing list