Skip to content

Commit a2dcc88

Browse files
authored
[AMDGPU][SDAG] Handle ISD::PTRADD in various special cases (#145330)
There are more places in SIISelLowering.cpp and AMDGPUISelDAGToDAG.cpp that check for ISD::ADD in a pointer context, but as far as I can tell those are only relevant for 32-bit pointer arithmetic (like frame indices/scratch addresses and LDS), for which we don't enable PTRADD generation yet. For SWDEV-516125.
1 parent e747223 commit a2dcc88

File tree

6 files changed

+104
-193
lines changed

6 files changed

+104
-193
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8600,7 +8600,7 @@ static bool isMemSrcFromConstant(SDValue Src, ConstantDataArraySlice &Slice) {
86008600
GlobalAddressSDNode *G = nullptr;
86018601
if (Src.getOpcode() == ISD::GlobalAddress)
86028602
G = cast<GlobalAddressSDNode>(Src);
8603-
else if (Src.getOpcode() == ISD::ADD &&
8603+
else if (Src->isAnyAdd() &&
86048604
Src.getOperand(0).getOpcode() == ISD::GlobalAddress &&
86058605
Src.getOperand(1).getOpcode() == ISD::Constant) {
86068606
G = cast<GlobalAddressSDNode>(Src.getOperand(0));

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,14 @@ bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth,
638638
// operands on the new node are also disjoint.
639639
SDNodeFlags Flags(Op->getFlags().hasDisjoint() ? SDNodeFlags::Disjoint
640640
: SDNodeFlags::None);
641+
unsigned Opcode = Op.getOpcode();
642+
if (Opcode == ISD::PTRADD) {
643+
// It isn't a ptradd anymore if it doesn't operate on the entire
644+
// pointer.
645+
Opcode = ISD::ADD;
646+
}
641647
SDValue X = DAG.getNode(
642-
Op.getOpcode(), dl, SmallVT,
648+
Opcode, dl, SmallVT,
643649
DAG.getNode(ISD::TRUNCATE, dl, SmallVT, Op.getOperand(0)),
644650
DAG.getNode(ISD::TRUNCATE, dl, SmallVT, Op.getOperand(1)), Flags);
645651
assert(DemandedSize <= SmallVTBits && "Narrowed below demanded bits?");
@@ -2860,6 +2866,11 @@ bool TargetLowering::SimplifyDemandedBits(
28602866
return TLO.CombineTo(Op, And1);
28612867
}
28622868
[[fallthrough]];
2869+
case ISD::PTRADD:
2870+
if (Op.getOperand(0).getValueType() != Op.getOperand(1).getValueType())
2871+
break;
2872+
// PTRADD behaves like ADD if pointers are represented as integers.
2873+
[[fallthrough]];
28632874
case ISD::ADD:
28642875
case ISD::SUB: {
28652876
// Add, Sub, and Mul don't demand any bits in positions beyond that
@@ -2969,9 +2980,9 @@ bool TargetLowering::SimplifyDemandedBits(
29692980

29702981
if (Op.getOpcode() == ISD::MUL) {
29712982
Known = KnownBits::mul(KnownOp0, KnownOp1);
2972-
} else { // Op.getOpcode() is either ISD::ADD or ISD::SUB.
2983+
} else { // Op.getOpcode() is either ISD::ADD, ISD::PTRADD, or ISD::SUB.
29732984
Known = KnownBits::computeForAddSub(
2974-
Op.getOpcode() == ISD::ADD, Flags.hasNoSignedWrap(),
2985+
Op.getOpcode() != ISD::SUB, Flags.hasNoSignedWrap(),
29752986
Flags.hasNoUnsignedWrap(), KnownOp0, KnownOp1);
29762987
}
29772988
break;
@@ -5679,7 +5690,7 @@ bool TargetLowering::isGAPlusOffset(SDNode *WN, const GlobalValue *&GA,
56795690
return true;
56805691
}
56815692

5682-
if (N->getOpcode() == ISD::ADD) {
5693+
if (N->isAnyAdd()) {
56835694
SDValue N1 = N->getOperand(0);
56845695
SDValue N2 = N->getOperand(1);
56855696
if (isGAPlusOffset(N1.getNode(), GA, Offset)) {

llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,7 @@ bool AMDGPUDAGToDAGISel::SelectMUBUF(SDValue Addr, SDValue &Ptr, SDValue &VAddr,
15311531
C1 = nullptr;
15321532
}
15331533

1534-
if (N0.getOpcode() == ISD::ADD) {
1534+
if (N0->isAnyAdd()) {
15351535
// (add N2, N3) -> addr64, or
15361536
// (add (add N2, N3), C1) -> addr64
15371537
SDValue N2 = N0.getOperand(0);
@@ -1993,7 +1993,7 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N, SDValue Addr,
19931993
}
19941994

19951995
// Match the variable offset.
1996-
if (Addr.getOpcode() == ISD::ADD) {
1996+
if (Addr->isAnyAdd()) {
19971997
LHS = Addr.getOperand(0);
19981998

19991999
if (!LHS->isDivergent()) {
@@ -2495,7 +2495,7 @@ bool AMDGPUDAGToDAGISel::SelectSMRDBaseOffset(SDNode *N, SDValue Addr,
24952495

24962496
SDValue N0, N1;
24972497
// Extract the base and offset if possible.
2498-
if (CurDAG->isBaseWithConstantOffset(Addr) || Addr.getOpcode() == ISD::ADD) {
2498+
if (Addr->isAnyAdd() || CurDAG->isADDLike(Addr)) {
24992499
N0 = Addr.getOperand(0);
25002500
N1 = Addr.getOperand(1);
25012501
} else if (getBaseWithOffsetUsingSplitOR(*CurDAG, Addr, N0, N1)) {

llvm/lib/Target/AMDGPU/SIISelLowering.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11298,7 +11298,7 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
1129811298
SDValue VOffset;
1129911299
// Try to split SAddr and VOffset. Global and LDS pointers share the same
1130011300
// immediate offset, so we cannot use a regular SelectGlobalSAddr().
11301-
if (Addr->isDivergent() && Addr.getOpcode() == ISD::ADD) {
11301+
if (Addr->isDivergent() && Addr->isAnyAdd()) {
1130211302
SDValue LHS = Addr.getOperand(0);
1130311303
SDValue RHS = Addr.getOperand(1);
1130411304

@@ -12916,8 +12916,7 @@ SDValue SITargetLowering::performSHLPtrCombine(SDNode *N, unsigned AddrSpace,
1291612916

1291712917
// We only do this to handle cases where it's profitable when there are
1291812918
// multiple uses of the add, so defer to the standard combine.
12919-
if ((N0.getOpcode() != ISD::ADD && N0.getOpcode() != ISD::OR) ||
12920-
N0->hasOneUse())
12919+
if ((!N0->isAnyAdd() && N0.getOpcode() != ISD::OR) || N0->hasOneUse())
1292112920
return SDValue();
1292212921

1292312922
const ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N1);
@@ -12956,6 +12955,8 @@ SDValue SITargetLowering::performSHLPtrCombine(SDNode *N, unsigned AddrSpace,
1295612955
N->getFlags().hasNoUnsignedWrap() &&
1295712956
(N0.getOpcode() == ISD::OR || N0->getFlags().hasNoUnsignedWrap()));
1295812957

12958+
// Use ISD::ADD even if the original operation was ISD::PTRADD, since we can't
12959+
// be sure that the new left operand is a proper base pointer.
1295912960
return DAG.getNode(ISD::ADD, SL, VT, ShlX, COffset, Flags);
1296012961
}
1296112962

llvm/test/CodeGen/AMDGPU/ptradd-sdag-mubuf.ll

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,26 @@
55
; Test PTRADD handling in AMDGPUDAGToDAGISel::SelectMUBUF.
66

77
define amdgpu_kernel void @v_add_i32(ptr addrspace(1) %out, ptr addrspace(1) %in) {
8-
; GFX6_PTRADD-LABEL: v_add_i32:
9-
; GFX6_PTRADD: ; %bb.0:
10-
; GFX6_PTRADD-NEXT: s_load_dwordx4 s[0:3], s[8:9], 0x0
11-
; GFX6_PTRADD-NEXT: v_lshlrev_b32_e32 v0, 2, v0
12-
; GFX6_PTRADD-NEXT: s_mov_b32 s7, 0x100f000
13-
; GFX6_PTRADD-NEXT: s_mov_b32 s10, 0
14-
; GFX6_PTRADD-NEXT: s_mov_b32 s11, s7
15-
; GFX6_PTRADD-NEXT: s_waitcnt lgkmcnt(0)
16-
; GFX6_PTRADD-NEXT: v_mov_b32_e32 v1, s3
17-
; GFX6_PTRADD-NEXT: v_add_i32_e32 v0, vcc, s2, v0
18-
; GFX6_PTRADD-NEXT: v_addc_u32_e32 v1, vcc, 0, v1, vcc
19-
; GFX6_PTRADD-NEXT: s_mov_b32 s8, s10
20-
; GFX6_PTRADD-NEXT: s_mov_b32 s9, s10
21-
; GFX6_PTRADD-NEXT: buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
22-
; GFX6_PTRADD-NEXT: s_waitcnt vmcnt(0)
23-
; GFX6_PTRADD-NEXT: buffer_load_dword v0, v[0:1], s[8:11], 0 addr64 offset:4 glc
24-
; GFX6_PTRADD-NEXT: s_waitcnt vmcnt(0)
25-
; GFX6_PTRADD-NEXT: s_mov_b32 s6, -1
26-
; GFX6_PTRADD-NEXT: s_mov_b32 s4, s0
27-
; GFX6_PTRADD-NEXT: s_mov_b32 s5, s1
28-
; GFX6_PTRADD-NEXT: v_add_i32_e32 v0, vcc, v2, v0
29-
; GFX6_PTRADD-NEXT: buffer_store_dword v0, off, s[4:7], 0
30-
; GFX6_PTRADD-NEXT: s_endpgm
31-
;
32-
; GFX6_LEGACY-LABEL: v_add_i32:
33-
; GFX6_LEGACY: ; %bb.0:
34-
; GFX6_LEGACY-NEXT: s_load_dwordx4 s[0:3], s[8:9], 0x0
35-
; GFX6_LEGACY-NEXT: s_mov_b32 s7, 0x100f000
36-
; GFX6_LEGACY-NEXT: s_mov_b32 s10, 0
37-
; GFX6_LEGACY-NEXT: s_mov_b32 s11, s7
38-
; GFX6_LEGACY-NEXT: v_lshlrev_b32_e32 v0, 2, v0
39-
; GFX6_LEGACY-NEXT: s_waitcnt lgkmcnt(0)
40-
; GFX6_LEGACY-NEXT: s_mov_b64 s[8:9], s[2:3]
41-
; GFX6_LEGACY-NEXT: v_mov_b32_e32 v1, 0
42-
; GFX6_LEGACY-NEXT: buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
43-
; GFX6_LEGACY-NEXT: s_waitcnt vmcnt(0)
44-
; GFX6_LEGACY-NEXT: buffer_load_dword v0, v[0:1], s[8:11], 0 addr64 offset:4 glc
45-
; GFX6_LEGACY-NEXT: s_waitcnt vmcnt(0)
46-
; GFX6_LEGACY-NEXT: s_mov_b32 s6, -1
47-
; GFX6_LEGACY-NEXT: s_mov_b32 s4, s0
48-
; GFX6_LEGACY-NEXT: s_mov_b32 s5, s1
49-
; GFX6_LEGACY-NEXT: v_add_i32_e32 v0, vcc, v2, v0
50-
; GFX6_LEGACY-NEXT: buffer_store_dword v0, off, s[4:7], 0
51-
; GFX6_LEGACY-NEXT: s_endpgm
8+
; GFX6-LABEL: v_add_i32:
9+
; GFX6: ; %bb.0:
10+
; GFX6-NEXT: s_load_dwordx4 s[0:3], s[8:9], 0x0
11+
; GFX6-NEXT: s_mov_b32 s7, 0x100f000
12+
; GFX6-NEXT: s_mov_b32 s10, 0
13+
; GFX6-NEXT: s_mov_b32 s11, s7
14+
; GFX6-NEXT: v_lshlrev_b32_e32 v0, 2, v0
15+
; GFX6-NEXT: s_waitcnt lgkmcnt(0)
16+
; GFX6-NEXT: s_mov_b64 s[8:9], s[2:3]
17+
; GFX6-NEXT: v_mov_b32_e32 v1, 0
18+
; GFX6-NEXT: buffer_load_dword v2, v[0:1], s[8:11], 0 addr64 glc
19+
; GFX6-NEXT: s_waitcnt vmcnt(0)
20+
; GFX6-NEXT: buffer_load_dword v0, v[0:1], s[8:11], 0 addr64 offset:4 glc
21+
; GFX6-NEXT: s_waitcnt vmcnt(0)
22+
; GFX6-NEXT: s_mov_b32 s6, -1
23+
; GFX6-NEXT: s_mov_b32 s4, s0
24+
; GFX6-NEXT: s_mov_b32 s5, s1
25+
; GFX6-NEXT: v_add_i32_e32 v0, vcc, v2, v0
26+
; GFX6-NEXT: buffer_store_dword v0, off, s[4:7], 0
27+
; GFX6-NEXT: s_endpgm
5228
%tid = call i32 @llvm.amdgcn.workitem.id.x()
5329
%gep = getelementptr inbounds i32, ptr addrspace(1) %in, i32 %tid
5430
%b_ptr = getelementptr i32, ptr addrspace(1) %gep, i32 1
@@ -60,4 +36,5 @@ define amdgpu_kernel void @v_add_i32(ptr addrspace(1) %out, ptr addrspace(1) %in
6036
}
6137

6238
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
63-
; GFX6: {{.*}}
39+
; GFX6_LEGACY: {{.*}}
40+
; GFX6_PTRADD: {{.*}}

0 commit comments

Comments
 (0)