Skip to content

Commit f7d1baa

Browse files
committed
[KnownBits] Return zero instead of unknown for always poison shifts
For always poison shifts, any KnownBits return value is valid. Currently we return unknown, but returning zero is generally more profitable. We had some code in ValueTracking that tried to do this, but was actually dead code. Differential Revision: https://reviews.llvm.org/D150648
1 parent 35ce741 commit f7d1baa

File tree

12 files changed

+39
-84
lines changed

12 files changed

+39
-84
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -994,13 +994,6 @@ static void computeKnownBitsFromShiftOperator(
994994

995995
if (ShiftAmtIsConstant) {
996996
Known = KF(Known2, Known);
997-
998-
// If the known bits conflict, this must be an overflowing left shift, so
999-
// the shift result is poison. We can return anything we want. Choose 0 for
1000-
// the best folding opportunity.
1001-
if (Known.hasConflict())
1002-
Known.setAllZero();
1003-
1004997
return;
1005998
}
1006999

llvm/lib/Support/KnownBits.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,11 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
183183
unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
184184

185185
APInt MinShiftAmount = RHS.getMinValue();
186-
if (MinShiftAmount.uge(BitWidth))
187-
// Always poison. Return unknown because we don't like returning conflict.
186+
if (MinShiftAmount.uge(BitWidth)) {
187+
// Always poison. Return zero because we don't like returning conflict.
188+
Known.setAllZero();
188189
return Known;
190+
}
189191

190192
// Minimum shift amount low bits are known zero.
191193
MinTrailingZeros += MinShiftAmount.getZExtValue();
@@ -240,9 +242,11 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
240242

241243
// Minimum shift amount high bits are known zero.
242244
APInt MinShiftAmount = RHS.getMinValue();
243-
if (MinShiftAmount.uge(BitWidth))
244-
// Always poison. Return unknown because we don't like returning conflict.
245+
if (MinShiftAmount.uge(BitWidth)) {
246+
// Always poison. Return zero because we don't like returning conflict.
247+
Known.setAllZero();
245248
return Known;
249+
}
246250

247251
MinLeadingZeros += MinShiftAmount.getZExtValue();
248252
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
@@ -295,9 +299,11 @@ KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
295299

296300
// Minimum shift amount high bits are known sign bits.
297301
APInt MinShiftAmount = RHS.getMinValue();
298-
if (MinShiftAmount.uge(BitWidth))
299-
// Always poison. Return unknown because we don't like returning conflict.
302+
if (MinShiftAmount.uge(BitWidth)) {
303+
// Always poison. Return zero because we don't like returning conflict.
304+
Known.setAllZero();
300305
return Known;
306+
}
301307

302308
if (MinLeadingZeros) {
303309
MinLeadingZeros += MinShiftAmount.getZExtValue();

llvm/test/Analysis/ScalarEvolution/ashr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ define i32 @t4(i32 %x, i32 %y) {
5151
; CHECK-LABEL: 't4'
5252
; CHECK-NEXT: Classifying expressions for: @t4
5353
; CHECK-NEXT: %i0 = ashr exact i32 %x, 32
54-
; CHECK-NEXT: --> %i0 U: full-set S: full-set
54+
; CHECK-NEXT: --> %i0 U: [0,1) S: [0,1)
5555
; CHECK-NEXT: Determining loop execution counts for: @t4
5656
;
5757
%i0 = ashr exact i32 %x, 32

llvm/test/CodeGen/AArch64/GlobalISel/form-bitfield-extract-from-sextinreg.mir

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ body: |
9595
; CHECK-NEXT: %x:_(s32) = COPY $w0
9696
; CHECK-NEXT: %lsb:_(s32) = G_CONSTANT i32 32
9797
; CHECK-NEXT: %shift:_(s32) = G_ASHR %x, %lsb(s32)
98-
; CHECK-NEXT: %sext_inreg:_(s32) = G_SEXT_INREG %shift, 1
99-
; CHECK-NEXT: $w0 = COPY %sext_inreg(s32)
98+
; CHECK-NEXT: $w0 = COPY %shift(s32)
10099
; CHECK-NEXT: RET_ReallyLR implicit $w0
101100
%x:_(s32) = COPY $w0
102101
%lsb:_(s32) = G_CONSTANT i32 32
@@ -122,8 +121,7 @@ body: |
122121
; CHECK-NEXT: %x:_(s32) = COPY $w0
123122
; CHECK-NEXT: %lsb:_(s32) = G_CONSTANT i32 -1
124123
; CHECK-NEXT: %shift:_(s32) = G_ASHR %x, %lsb(s32)
125-
; CHECK-NEXT: %sext_inreg:_(s32) = G_SEXT_INREG %shift, 1
126-
; CHECK-NEXT: $w0 = COPY %sext_inreg(s32)
124+
; CHECK-NEXT: $w0 = COPY %shift(s32)
127125
; CHECK-NEXT: RET_ReallyLR implicit $w0
128126
%x:_(s32) = COPY $w0
129127
%lsb:_(s32) = G_CONSTANT i32 -1

llvm/test/CodeGen/LoongArch/rotl-rotr.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,9 @@ define i64 @rotl_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
374374
define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
375375
; LA32-LABEL: rotl_64_mask_or_128_or_64:
376376
; LA32: # %bb.0:
377-
; LA32-NEXT: sll.w $a3, $a0, $a2
378377
; LA32-NEXT: sub.w $a0, $zero, $a2
379378
; LA32-NEXT: srl.w $a0, $a1, $a0
380-
; LA32-NEXT: move $a1, $a3
379+
; LA32-NEXT: move $a1, $zero
381380
; LA32-NEXT: ret
382381
;
383382
; LA64-LABEL: rotl_64_mask_or_128_or_64:
@@ -499,10 +498,8 @@ define i64 @rotr_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
499498
define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
500499
; LA32-LABEL: rotr_64_mask_or_128_or_64:
501500
; LA32: # %bb.0:
502-
; LA32-NEXT: srl.w $a3, $a1, $a2
503-
; LA32-NEXT: sub.w $a1, $zero, $a2
504-
; LA32-NEXT: sll.w $a1, $a0, $a1
505-
; LA32-NEXT: move $a0, $a3
501+
; LA32-NEXT: srl.w $a0, $a1, $a2
502+
; LA32-NEXT: move $a1, $zero
506503
; LA32-NEXT: ret
507504
;
508505
; LA64-LABEL: rotr_64_mask_or_128_or_64:

llvm/test/CodeGen/RISCV/rotl-rotr.ll

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -516,20 +516,15 @@ define i32 @rotl_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind {
516516
define i32 @rotl_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind {
517517
; RV32I-LABEL: rotl_32_mask_or_64_or_32:
518518
; RV32I: # %bb.0:
519-
; RV32I-NEXT: ori a2, a1, 64
520-
; RV32I-NEXT: sll a2, a0, a2
521519
; RV32I-NEXT: neg a1, a1
522520
; RV32I-NEXT: ori a1, a1, 32
523521
; RV32I-NEXT: srl a0, a0, a1
524-
; RV32I-NEXT: or a0, a2, a0
525522
; RV32I-NEXT: ret
526523
;
527524
; RV64I-LABEL: rotl_32_mask_or_64_or_32:
528525
; RV64I: # %bb.0:
529-
; RV64I-NEXT: sllw a2, a0, a1
530526
; RV64I-NEXT: negw a1, a1
531527
; RV64I-NEXT: srlw a0, a0, a1
532-
; RV64I-NEXT: or a0, a2, a0
533528
; RV64I-NEXT: ret
534529
;
535530
; RV32ZBB-LABEL: rotl_32_mask_or_64_or_32:
@@ -670,20 +665,13 @@ define i32 @rotr_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind {
670665
define i32 @rotr_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind {
671666
; RV32I-LABEL: rotr_32_mask_or_64_or_32:
672667
; RV32I: # %bb.0:
673-
; RV32I-NEXT: ori a2, a1, 64
674-
; RV32I-NEXT: srl a2, a0, a2
675-
; RV32I-NEXT: neg a1, a1
676-
; RV32I-NEXT: ori a1, a1, 32
677-
; RV32I-NEXT: sll a0, a0, a1
678-
; RV32I-NEXT: or a0, a2, a0
668+
; RV32I-NEXT: ori a1, a1, 64
669+
; RV32I-NEXT: srl a0, a0, a1
679670
; RV32I-NEXT: ret
680671
;
681672
; RV64I-LABEL: rotr_32_mask_or_64_or_32:
682673
; RV64I: # %bb.0:
683-
; RV64I-NEXT: srlw a2, a0, a1
684-
; RV64I-NEXT: negw a1, a1
685-
; RV64I-NEXT: sllw a0, a0, a1
686-
; RV64I-NEXT: or a0, a2, a0
674+
; RV64I-NEXT: srlw a0, a0, a1
687675
; RV64I-NEXT: ret
688676
;
689677
; RV32ZBB-LABEL: rotr_32_mask_or_64_or_32:
@@ -1013,28 +1001,23 @@ define i64 @rotl_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
10131001
define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
10141002
; RV32I-LABEL: rotl_64_mask_or_128_or_64:
10151003
; RV32I: # %bb.0:
1016-
; RV32I-NEXT: sll a3, a0, a2
10171004
; RV32I-NEXT: neg a0, a2
10181005
; RV32I-NEXT: srl a0, a1, a0
1019-
; RV32I-NEXT: mv a1, a3
1006+
; RV32I-NEXT: li a1, 0
10201007
; RV32I-NEXT: ret
10211008
;
10221009
; RV64I-LABEL: rotl_64_mask_or_128_or_64:
10231010
; RV64I: # %bb.0:
1024-
; RV64I-NEXT: ori a2, a1, 128
1025-
; RV64I-NEXT: sll a2, a0, a2
10261011
; RV64I-NEXT: negw a1, a1
10271012
; RV64I-NEXT: ori a1, a1, 64
10281013
; RV64I-NEXT: srl a0, a0, a1
1029-
; RV64I-NEXT: or a0, a2, a0
10301014
; RV64I-NEXT: ret
10311015
;
10321016
; RV32ZBB-LABEL: rotl_64_mask_or_128_or_64:
10331017
; RV32ZBB: # %bb.0:
1034-
; RV32ZBB-NEXT: sll a3, a0, a2
10351018
; RV32ZBB-NEXT: neg a0, a2
10361019
; RV32ZBB-NEXT: srl a0, a1, a0
1037-
; RV32ZBB-NEXT: mv a1, a3
1020+
; RV32ZBB-NEXT: li a1, 0
10381021
; RV32ZBB-NEXT: ret
10391022
;
10401023
; RV64ZBB-LABEL: rotl_64_mask_or_128_or_64:
@@ -1044,10 +1027,9 @@ define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
10441027
;
10451028
; RV32XTHEADBB-LABEL: rotl_64_mask_or_128_or_64:
10461029
; RV32XTHEADBB: # %bb.0:
1047-
; RV32XTHEADBB-NEXT: sll a3, a0, a2
10481030
; RV32XTHEADBB-NEXT: neg a0, a2
10491031
; RV32XTHEADBB-NEXT: srl a0, a1, a0
1050-
; RV32XTHEADBB-NEXT: mv a1, a3
1032+
; RV32XTHEADBB-NEXT: li a1, 0
10511033
; RV32XTHEADBB-NEXT: ret
10521034
;
10531035
; RV64XTHEADBB-LABEL: rotl_64_mask_or_128_or_64:
@@ -1359,28 +1341,20 @@ define i64 @rotr_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
13591341
define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
13601342
; RV32I-LABEL: rotr_64_mask_or_128_or_64:
13611343
; RV32I: # %bb.0:
1362-
; RV32I-NEXT: srl a3, a1, a2
1363-
; RV32I-NEXT: neg a1, a2
1364-
; RV32I-NEXT: sll a1, a0, a1
1365-
; RV32I-NEXT: mv a0, a3
1344+
; RV32I-NEXT: srl a0, a1, a2
1345+
; RV32I-NEXT: li a1, 0
13661346
; RV32I-NEXT: ret
13671347
;
13681348
; RV64I-LABEL: rotr_64_mask_or_128_or_64:
13691349
; RV64I: # %bb.0:
1370-
; RV64I-NEXT: ori a2, a1, 128
1371-
; RV64I-NEXT: srl a2, a0, a2
1372-
; RV64I-NEXT: negw a1, a1
1373-
; RV64I-NEXT: ori a1, a1, 64
1374-
; RV64I-NEXT: sll a0, a0, a1
1375-
; RV64I-NEXT: or a0, a2, a0
1350+
; RV64I-NEXT: ori a1, a1, 128
1351+
; RV64I-NEXT: srl a0, a0, a1
13761352
; RV64I-NEXT: ret
13771353
;
13781354
; RV32ZBB-LABEL: rotr_64_mask_or_128_or_64:
13791355
; RV32ZBB: # %bb.0:
1380-
; RV32ZBB-NEXT: srl a3, a1, a2
1381-
; RV32ZBB-NEXT: neg a1, a2
1382-
; RV32ZBB-NEXT: sll a1, a0, a1
1383-
; RV32ZBB-NEXT: mv a0, a3
1356+
; RV32ZBB-NEXT: srl a0, a1, a2
1357+
; RV32ZBB-NEXT: li a1, 0
13841358
; RV32ZBB-NEXT: ret
13851359
;
13861360
; RV64ZBB-LABEL: rotr_64_mask_or_128_or_64:
@@ -1390,10 +1364,8 @@ define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
13901364
;
13911365
; RV32XTHEADBB-LABEL: rotr_64_mask_or_128_or_64:
13921366
; RV32XTHEADBB: # %bb.0:
1393-
; RV32XTHEADBB-NEXT: srl a3, a1, a2
1394-
; RV32XTHEADBB-NEXT: neg a1, a2
1395-
; RV32XTHEADBB-NEXT: sll a1, a0, a1
1396-
; RV32XTHEADBB-NEXT: mv a0, a3
1367+
; RV32XTHEADBB-NEXT: srl a0, a1, a2
1368+
; RV32XTHEADBB-NEXT: li a1, 0
13971369
; RV32XTHEADBB-NEXT: ret
13981370
;
13991371
; RV64XTHEADBB-LABEL: rotr_64_mask_or_128_or_64:

llvm/test/Transforms/InstCombine/not-add.ll

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,6 @@ cond.end:
170170
define void @pr50370(i32 %x) {
171171
; CHECK-LABEL: @pr50370(
172172
; CHECK-NEXT: entry:
173-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 1
174-
; CHECK-NEXT: [[B15:%.*]] = srem i32 ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (ptr @g, ptr null) to i32), i32 65537)), [[XOR]]
175-
; CHECK-NEXT: [[B12:%.*]] = add nsw i32 [[B15]], ashr (i32 65536, i32 or (i32 zext (i1 icmp eq (ptr @g, ptr null) to i32), i32 65537))
176-
; CHECK-NEXT: [[B:%.*]] = xor i32 [[B12]], -1
177-
; CHECK-NEXT: store i32 [[B]], ptr undef, align 4
178173
; CHECK-NEXT: ret void
179174
;
180175
entry:

llvm/test/Transforms/InstCombine/oss_fuzz_32759.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ define i1 @oss_fuzz_32759(i1 %y, i1 %c1) {
99
; CHECK: cond.true:
1010
; CHECK-NEXT: br label [[END]]
1111
; CHECK: end:
12-
; CHECK-NEXT: ret i1 false
12+
; CHECK-NEXT: ret i1 [[C1]]
1313
;
1414
entry:
1515
br i1 %c1, label %cond.true, label %end

llvm/test/Transforms/InstCombine/shift.ll

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,12 +1743,6 @@ define void @ashr_out_of_range(ptr %A) {
17431743
; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26135
17441744
define void @ashr_out_of_range_1(ptr %A) {
17451745
; CHECK-LABEL: @ashr_out_of_range_1(
1746-
; CHECK-NEXT: [[L:%.*]] = load i177, ptr [[A:%.*]], align 4
1747-
; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[A]], i64 -1
1748-
; CHECK-NEXT: [[B24_LOBIT:%.*]] = ashr i177 [[L]], 175
1749-
; CHECK-NEXT: [[TMP1:%.*]] = trunc i177 [[B24_LOBIT]] to i64
1750-
; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP1]]
1751-
; CHECK-NEXT: store i177 0, ptr [[G62]], align 4
17521746
; CHECK-NEXT: ret void
17531747
;
17541748
%L = load i177, ptr %A, align 4

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ TEST_F(ValueTrackingTest, ComputeNumSignBits_PR32045) {
694694
" %A = ashr i32 %a, -1\n"
695695
" ret i32 %A\n"
696696
"}\n");
697-
EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 1u);
697+
EXPECT_EQ(ComputeNumSignBits(A, M->getDataLayout()), 32u);
698698
}
699699

700700
// No guarantees for canonical IR in this analysis, so this just bails out.

0 commit comments

Comments
 (0)