Skip to content

Commit b47ff36

Browse files
authored
[InstCombine] Drop exact flag instead of increasing demanded bits (#70311)
Demanded bit simplification for lshr/ashr will currently demand the low bits if the exact flag is set. This is because these bits must be zero to satisfy the flag. However, this means that our demanded bits simplification is worse for lshr/ashr exact than it is for plain lshr/ashr, which is generally not desirable. Instead, drop the exact flag if a demanded bits simplification of the operand succeeds, which may no longer satisfy the exact flag. This matches what we do for the exact flag on udiv, as well as the nuw/nsw flags on add/sub/mul.
1 parent 5e07481 commit b47ff36

File tree

4 files changed

+14
-21
lines changed

4 files changed

+14
-21
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -698,14 +698,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
698698

699699
// Unsigned shift right.
700700
APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt));
701-
702-
// If the shift is exact, then it does demand the low bits (and knows that
703-
// they are zero).
704-
if (cast<LShrOperator>(I)->isExact())
705-
DemandedMaskIn.setLowBits(ShiftAmt);
706-
707-
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1))
701+
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1)) {
702+
// exact flag may not longer hold.
703+
I->dropPoisonGeneratingFlags();
708704
return I;
705+
}
709706
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
710707
Known.Zero.lshrInPlace(ShiftAmt);
711708
Known.One.lshrInPlace(ShiftAmt);
@@ -747,13 +744,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
747744
if (DemandedMask.countl_zero() <= ShiftAmt)
748745
DemandedMaskIn.setSignBit();
749746

750-
// If the shift is exact, then it does demand the low bits (and knows that
751-
// they are zero).
752-
if (cast<AShrOperator>(I)->isExact())
753-
DemandedMaskIn.setLowBits(ShiftAmt);
754-
755-
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1))
747+
if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1)) {
748+
// exact flag may not longer hold.
749+
I->dropPoisonGeneratingFlags();
756750
return I;
751+
}
757752

758753
assert(!Known.hasConflict() && "Bits known to be one AND zero?");
759754
// Compute the new bits that are at the top now plus sign bits.

llvm/test/Transforms/InstCombine/cast.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ define i64 @test83(i16 %a, i64 %k) {
13181318
define i8 @test84(i32 %a) {
13191319
; ALL-LABEL: @test84(
13201320
; ALL-NEXT: [[ADD:%.*]] = add i32 [[A:%.*]], 2130706432
1321-
; ALL-NEXT: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
1321+
; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], 23
13221322
; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i8
13231323
; ALL-NEXT: ret i8 [[TRUNC]]
13241324
;
@@ -1331,7 +1331,7 @@ define i8 @test84(i32 %a) {
13311331
define i8 @test85(i32 %a) {
13321332
; ALL-LABEL: @test85(
13331333
; ALL-NEXT: [[ADD:%.*]] = add i32 [[A:%.*]], 2130706432
1334-
; ALL-NEXT: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
1334+
; ALL-NEXT: [[SHR:%.*]] = lshr i32 [[ADD]], 23
13351335
; ALL-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i8
13361336
; ALL-NEXT: ret i8 [[TRUNC]]
13371337
;

llvm/test/Transforms/InstCombine/select-2.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ define float @t3(float %x, float %y) {
4545

4646
define i8 @ashr_exact_poison_constant_fold(i1 %b, i8 %x) {
4747
; CHECK-LABEL: @ashr_exact_poison_constant_fold(
48-
; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i8 [[X:%.*]], 3
48+
; CHECK-NEXT: [[TMP1:%.*]] = ashr i8 [[X:%.*]], 3
4949
; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i8 [[TMP1]], i8 5
5050
; CHECK-NEXT: ret i8 [[R]]
5151
;

llvm/test/Transforms/InstCombine/shift.ll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,9 +2141,8 @@ define i16 @lshr_and_not_demanded(i8 %x) {
21412141

21422142
define i16 @lshr_exact_and_not_demanded(i8 %x) {
21432143
; CHECK-LABEL: @lshr_exact_and_not_demanded(
2144-
; CHECK-NEXT: [[Y:%.*]] = and i8 [[X:%.*]], -2
2145-
; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[Y]] to i16
2146-
; CHECK-NEXT: [[SHR:%.*]] = lshr exact i16 [[Y_EXT]], 1
2144+
; CHECK-NEXT: [[Y_EXT:%.*]] = sext i8 [[X:%.*]] to i16
2145+
; CHECK-NEXT: [[SHR:%.*]] = lshr i16 [[Y_EXT]], 1
21472146
; CHECK-NEXT: ret i16 [[SHR]]
21482147
;
21492148
%y = and i8 %x, -2
@@ -2177,8 +2176,7 @@ define i16 @ashr_umax_not_demanded(i16 %x) {
21772176

21782177
define i16 @ashr_exact_umax_not_demanded(i16 %x) {
21792178
; CHECK-LABEL: @ashr_exact_umax_not_demanded(
2180-
; CHECK-NEXT: [[Y:%.*]] = call i16 @llvm.umax.i16(i16 [[X:%.*]], i16 1)
2181-
; CHECK-NEXT: [[SHR:%.*]] = ashr exact i16 [[Y]], 1
2179+
; CHECK-NEXT: [[SHR:%.*]] = ashr i16 [[X:%.*]], 1
21822180
; CHECK-NEXT: ret i16 [[SHR]]
21832181
;
21842182
%y = call i16 @llvm.umax.i16(i16 %x, i16 1)

0 commit comments

Comments
 (0)