diff options
-rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 16 | ||||
-rw-r--r-- | llvm/test/Transforms/SCCP/pr27712.ll | 30 | ||||
-rw-r--r-- | llvm/test/Transforms/SCCP/ub-shift.ll | 69 |
3 files changed, 115 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index 75414ef3864..c75c948329c 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -1416,6 +1416,14 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { // X >>a undef -> undef. if (Op1LV.isUndefined()) break; + // Shifting by the bitwidth or more is undefined. + if (Op1LV.isConstant()) { + auto *ShiftAmt = Op1LV.getConstantInt(); + if (ShiftAmt->getLimitedValue() >= + ShiftAmt->getType()->getScalarSizeInBits()) + break; + } + // undef >>a X -> all ones markForcedConstant(&I, Constant::getAllOnesValue(ITy)); return true; @@ -1425,6 +1433,14 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { // X >> undef -> undef. if (Op1LV.isUndefined()) break; + // Shifting by the bitwidth or more is undefined. + if (Op1LV.isConstant()) { + auto *ShiftAmt = Op1LV.getConstantInt(); + if (ShiftAmt->getLimitedValue() >= + ShiftAmt->getType()->getScalarSizeInBits()) + break; + } + // undef << X -> 0 // undef >> X -> 0 markForcedConstant(&I, Constant::getNullValue(ITy)); diff --git a/llvm/test/Transforms/SCCP/pr27712.ll b/llvm/test/Transforms/SCCP/pr27712.ll new file mode 100644 index 00000000000..b41c3981d53 --- /dev/null +++ b/llvm/test/Transforms/SCCP/pr27712.ll @@ -0,0 +1,30 @@ +; RUN: opt -sccp -S < %s | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() { +entry: + br label %lbl_1154 + +lbl_1154: + %b0.0 = phi i32 [ -119, %entry ], [ 0, %lbl_1154 ] + %cmp11 = icmp slt i32 %b0.0, 0 + %shl.op = shl i32 33554432, %b0.0 + %cmp1445 = icmp ult i32 %shl.op, 33554432 + %cmp14 = or i1 %cmp11, %cmp1445 + br i1 %cmp14, label %lbl_1154, label %if.end19 + +if.end19: + br i1 %cmp11, label %if.then22, label %cleanup26 + +if.then22: + tail call void @abort() + unreachable + +cleanup26: + ret i32 %shl.op +} +; CHECK-LABEL: define i32 @main( +; CHECK-NOT: ret i32 undef + +declare void @abort() diff --git a/llvm/test/Transforms/SCCP/ub-shift.ll b/llvm/test/Transforms/SCCP/ub-shift.ll new file mode 100644 index 00000000000..3fb2d97457d --- /dev/null +++ b/llvm/test/Transforms/SCCP/ub-shift.ll @@ -0,0 +1,69 @@ +; RUN: opt < %s -sccp -S | FileCheck %s + +; CHECK-LABEL: shift_undef_64 +define void @shift_undef_64(i64* %p) { + %r1 = lshr i64 -1, 4294967296 ; 2^32 + ; CHECK: store i64 undef + store i64 %r1, i64* %p + + %r2 = ashr i64 -1, 4294967297 ; 2^32 + 1 + ; CHECK: store i64 undef + store i64 %r2, i64* %p + + %r3 = shl i64 -1, 4294967298 ; 2^32 + 2 + ; CHECK: store i64 undef + store i64 %r3, i64* %p + + ret void +} + +; CHECK-LABEL: shift_undef_65 +define void @shift_undef_65(i65* %p) { + %r1 = lshr i65 2, 18446744073709551617 + ; CHECK: store i65 undef + store i65 %r1, i65* %p + + %r2 = ashr i65 4, 18446744073709551617 + ; CHECK: store i65 undef + store i65 %r2, i65* %p + + %r3 = shl i65 1, 18446744073709551617 + ; CHECK: store i65 undef + store i65 %r3, i65* %p + + ret void +} + +; CHECK-LABEL: shift_undef_256 +define void @shift_undef_256(i256* %p) { + %r1 = lshr i256 2, 18446744073709551617 + ; CHECK: store i256 undef + store i256 %r1, i256* %p + + %r2 = ashr i256 4, 18446744073709551618 + ; CHECK: store i256 undef + store i256 %r2, i256* %p + + %r3 = shl i256 1, 18446744073709551619 + ; CHECK: store i256 undef + store i256 %r3, i256* %p + + ret void +} + +; CHECK-LABEL: shift_undef_511 +define void @shift_undef_511(i511* %p) { + %r1 = lshr i511 -1, 1208925819614629174706276 ; 2^80 + 100 + ; CHECK: store i511 undef + store i511 %r1, i511* %p + + %r2 = ashr i511 -2, 1208925819614629174706200 + ; CHECK: store i511 undef + store i511 %r2, i511* %p + + %r3 = shl i511 -3, 1208925819614629174706180 + ; CHECK: store i511 undef + store i511 %r3, i511* %p + + ret void +} |