Skip to content

Instantly share code, notes, and snippets.

@nikic
Created March 20, 2020 10:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/29135f304f7cf9de6d18dff7ca12659a to your computer and use it in GitHub Desktop.
Save nikic/29135f304f7cf9de6d18dff7ca12659a to your computer and use it in GitHub Desktop.
commit 5823f08dbc315ef37a252ae1f9e096cc682eb08e
Author: Nikita Popov <nikita.ppv@gmail.com>
Date: Fri Mar 20 10:42:55 2020 +0100
Check for poison nowrap shift
diff --git llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index aa5d33ce8ac..145ef0082b3 100644
--- llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -553,6 +553,19 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1))
return I;
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
+
+ bool Overflow;
+ if (IOp->hasNoSignedWrap()) {
+ (void) Known.One.sshl_ov(*SA, Overflow);
+ if (Overflow)
+ return UndefValue::get(I->getType());
+ }
+ if (IOp->hasNoUnsignedWrap()) {
+ (void) Known.One.ushl_ov(*SA, Overflow);
+ if (Overflow)
+ return UndefValue::get(I->getType());
+ }
+
Known.Zero <<= ShiftAmt;
Known.One <<= ShiftAmt;
// low bits known zero.
diff --git llvm/test/Analysis/ValueTracking/known-signbit-shift.ll llvm/test/Analysis/ValueTracking/known-signbit-shift.ll
index bd1902960f2..b00a4f83702 100644
--- llvm/test/Analysis/ValueTracking/known-signbit-shift.ll
+++ llvm/test/Analysis/ValueTracking/known-signbit-shift.ll
@@ -30,8 +30,7 @@ define i1 @test_shift_negative(i32 %a, i32 %b) {
; This test should not crash opt. The shift produces poison.
define i32 @test_no_sign_bit_conflict1(i1 %b) {
; CHECK-LABEL: @test_no_sign_bit_conflict1(
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i32 -2147221504, i32 -2147483648
-; CHECK-NEXT: ret i32 [[SEL]]
+; CHECK-NEXT: ret i32 undef
;
%sel = select i1 %b, i32 8193, i32 8192
%mul = shl nsw i32 %sel, 18
@@ -42,8 +41,7 @@ define i32 @test_no_sign_bit_conflict1(i1 %b) {
; This test should not crash opt. The shift produces poison.
define i32 @test_no_sign_bit_conflict2(i1 %b) {
; CHECK-LABEL: @test_no_sign_bit_conflict2(
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[B:%.*]], i32 2147221504, i32 2146959360
-; CHECK-NEXT: ret i32 [[SEL]]
+; CHECK-NEXT: ret i32 undef
;
%sel = select i1 %b, i32 -8193, i32 -8194
%mul = shl nsw i32 %sel, 18
diff --git llvm/test/Transforms/InstCombine/select-obo-peo-ops.ll llvm/test/Transforms/InstCombine/select-obo-peo-ops.ll
index 54c1d0f548c..07a0f9a8070 100644
--- llvm/test/Transforms/InstCombine/select-obo-peo-ops.ll
+++ llvm/test/Transforms/InstCombine/select-obo-peo-ops.ll
@@ -139,11 +139,7 @@ define i64 @test_shl__nuw_is_safe(i32 %x, i64 %y) {
define i32 @test_shl_nuw_nsw__nsw_is_safe(i32 %x) {
; CHECK-LABEL: @test_shl_nuw_nsw__nsw_is_safe(
-; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT: [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP4]]
+; CHECK-NEXT: ret i32 0
;
%1 = or i32 %x, -83886080
%2 = icmp eq i32 %1, -83886079
@@ -156,11 +152,7 @@ define i32 @test_shl_nuw_nsw__nsw_is_safe(i32 %x) {
define i32 @test_shl_nuw__nsw_is_safe(i32 %x) {
; CHECK-LABEL: @test_shl_nuw__nsw_is_safe(
-; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT: [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT: [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
-; CHECK-NEXT: ret i32 [[TMP4]]
+; CHECK-NEXT: ret i32 0
;
%1 = or i32 %x, -83886080
%2 = icmp eq i32 %1, -83886079
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment