Skip to content

Commit cab21d4

Browse files
committed
[DAG] computeKnownBits - Move (most) ISD::SHL handling into KnownBits::shl
As discussed on D90527, we should be be trying to move shift handling functionality into KnownBits to avoid code duplication in SelectionDAG/GlobalISel/ValueTracking. The refactor to use the KnownBits fixed/min/max constant helpers allows us to hit a couple of cases that we were missing before. We still need the getValidMinimumShiftAmountConstant case as KnownBits doesn't handle per-element vector cases.
1 parent a5bbefe commit cab21d4

File tree

5 files changed

+47
-32
lines changed

5 files changed

+47
-32
lines changed

llvm/include/llvm/Support/KnownBits.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ struct KnownBits {
270270
/// Compute known bits for smin(LHS, RHS).
271271
static KnownBits smin(const KnownBits &LHS, const KnownBits &RHS);
272272

273+
/// Compute known bits for shl(LHS, RHS).
274+
/// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
275+
static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS);
276+
273277
/// Insert the bits from a smaller known bits starting at bitPosition.
274278
void insertBits(const KnownBits &SubBits, unsigned BitPosition) {
275279
Zero.insertBits(SubBits.Zero, BitPosition);

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,19 +2960,8 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
29602960
}
29612961
case ISD::SHL:
29622962
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
2963-
2964-
if (const APInt *ShAmt = getValidShiftAmountConstant(Op, DemandedElts)) {
2965-
unsigned Shift = ShAmt->getZExtValue();
2966-
Known.Zero <<= Shift;
2967-
Known.One <<= Shift;
2968-
// Low bits are known zero.
2969-
Known.Zero.setLowBits(Shift);
2970-
break;
2971-
}
2972-
2973-
// No matter the shift amount, the trailing zeros will stay zero.
2974-
Known.Zero = APInt::getLowBitsSet(BitWidth, Known.countMinTrailingZeros());
2975-
Known.One.clearAllBits();
2963+
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
2964+
Known = KnownBits::shl(Known, Known2);
29762965

29772966
// Minimum shift low bits are known zero.
29782967
if (const APInt *ShMinAmt =

llvm/lib/Support/KnownBits.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,30 @@ KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
145145
return Flip(umax(Flip(LHS), Flip(RHS)));
146146
}
147147

148+
KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
149+
unsigned BitWidth = LHS.getBitWidth();
150+
KnownBits Known(BitWidth);
151+
152+
// If the shift amount is a valid constant then transform LHS directly.
153+
if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
154+
unsigned Shift = RHS.getConstant().getZExtValue();
155+
Known = LHS;
156+
Known.Zero <<= Shift;
157+
Known.One <<= Shift;
158+
// Low bits are known zero.
159+
Known.Zero.setLowBits(Shift);
160+
return Known;
161+
}
162+
163+
// Minimum shift amount low bits are known zero.
164+
if (RHS.getMinValue().ult(BitWidth))
165+
Known.Zero.setLowBits(RHS.getMinValue().getZExtValue());
166+
167+
// No matter the shift amount, the trailing zeros will stay zero.
168+
Known.Zero.setLowBits(LHS.countMinTrailingZeros());
169+
return Known;
170+
}
171+
148172
KnownBits KnownBits::abs() const {
149173
// If the source's MSB is zero then we know the rest of the bits already.
150174
if (isNonNegative())

llvm/test/CodeGen/PowerPC/pr44183.ll

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
22
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
33
; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s
4+
45
%struct.m.2.5.8.11 = type { %struct.l.0.3.6.9, [7 x i8], %struct.a.1.4.7.10 }
56
%struct.l.0.3.6.9 = type { i8 }
67
%struct.a.1.4.7.10 = type { [27 x i8], [0 x i32], [4 x i8] }
8+
79
define void @_ZN1m1nEv(%struct.m.2.5.8.11* %this) local_unnamed_addr nounwind align 2 {
810
; CHECK-LABEL: _ZN1m1nEv:
911
; CHECK: # %bb.0: # %entry
@@ -12,15 +14,12 @@ define void @_ZN1m1nEv(%struct.m.2.5.8.11* %this) local_unnamed_addr nounwind al
1214
; CHECK-NEXT: std r0, 16(r1)
1315
; CHECK-NEXT: stdu r1, -48(r1)
1416
; CHECK-NEXT: mr r30, r3
15-
; CHECK-NEXT: ld r4, 16(r30)
16-
; CHECK-NEXT: ld r5, 8(r30)
17-
; CHECK-NEXT: lwz r6, 36(r30)
18-
; CHECK-NEXT: rldicl r5, r5, 60, 4
19-
; CHECK-NEXT: sldi r4, r4, 60
20-
; CHECK-NEXT: or r4, r4, r5
21-
; CHECK-NEXT: rlwinm r3, r4, 31, 0, 0
22-
; CHECK-NEXT: clrlwi r4, r6, 31
23-
; CHECK-NEXT: or r4, r4, r3
17+
; CHECK-NEXT: ld r3, 8(r3)
18+
; CHECK-NEXT: lwz r4, 36(r30)
19+
; CHECK-NEXT: rldicl r3, r3, 60, 4
20+
; CHECK-NEXT: slwi r3, r3, 31
21+
; CHECK-NEXT: clrlwi r4, r4, 31
22+
; CHECK-NEXT: rlwimi r4, r3, 0, 0, 0
2423
; CHECK-NEXT: bl _ZN1llsE1d
2524
; CHECK-NEXT: nop
2625
; CHECK-NEXT: ld r3, 16(r30)
@@ -29,7 +28,7 @@ define void @_ZN1m1nEv(%struct.m.2.5.8.11* %this) local_unnamed_addr nounwind al
2928
; CHECK-NEXT: sldi r3, r3, 60
3029
; CHECK-NEXT: or r3, r3, r4
3130
; CHECK-NEXT: sldi r3, r3, 31
32-
; CHECK-NEXT: clrldi r4, r3, 32
31+
; CHECK-NEXT: rlwinm r4, r3, 0, 0, 0
3332
; CHECK-NEXT: bl _ZN1llsE1d
3433
; CHECK-NEXT: nop
3534
; CHECK-NEXT: addi r1, r1, 48

llvm/test/CodeGen/X86/pr32282.ll

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,17 @@ define void @foo(i64 %x) nounwind {
1313
; X86-LABEL: foo:
1414
; X86: # %bb.0:
1515
; X86-NEXT: pushl %eax
16-
; X86-NEXT: movl d, %eax
16+
; X86-NEXT: movl d+4, %eax
1717
; X86-NEXT: notl %eax
18-
; X86-NEXT: movl d+4, %ecx
18+
; X86-NEXT: movl d, %ecx
1919
; X86-NEXT: notl %ecx
20-
; X86-NEXT: andl $701685459, %ecx # imm = 0x29D2DED3
21-
; X86-NEXT: andl $-566231040, %eax # imm = 0xDE400000
22-
; X86-NEXT: shrdl $21, %ecx, %eax
23-
; X86-NEXT: shrl $21, %ecx
24-
; X86-NEXT: addl $7, %eax
25-
; X86-NEXT: adcl $0, %ecx
26-
; X86-NEXT: pushl %ecx
20+
; X86-NEXT: andl $-566231040, %ecx # imm = 0xDE400000
21+
; X86-NEXT: andl $701685459, %eax # imm = 0x29D2DED3
22+
; X86-NEXT: shrdl $21, %eax, %ecx
23+
; X86-NEXT: shrl $21, %eax
24+
; X86-NEXT: addl $7, %ecx
2725
; X86-NEXT: pushl %eax
26+
; X86-NEXT: pushl %ecx
2827
; X86-NEXT: pushl {{[0-9]+}}(%esp)
2928
; X86-NEXT: pushl {{[0-9]+}}(%esp)
3029
; X86-NEXT: calll __divdi3

0 commit comments

Comments
 (0)