-
-
Save nikic/29135f304f7cf9de6d18dff7ca12659a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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