Skip to content

Commit 083ff66

Browse files
committed
[AMDGPU][SDAG] Handle ISD::PTRADD in various special cases
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 ee350dc commit 083ff66

File tree

6 files changed

+105
-194
lines changed

6 files changed

+105
-194
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8219,7 +8219,7 @@ static bool isMemSrcFromConstant(SDValue Src, ConstantDataArraySlice &Slice) {
82198219
GlobalAddressSDNode *G = nullptr;
82208220
if (Src.getOpcode() == ISD::GlobalAddress)
82218221
G = cast<GlobalAddressSDNode>(Src);
8222-
else if (Src.getOpcode() == ISD::ADD &&
8222+
else if (Src->isAnyAdd() &&
82238223
Src.getOperand(0).getOpcode() == ISD::GlobalAddress &&
82248224
Src.getOperand(1).getOpcode() == ISD::Constant) {
82258225
G = cast<GlobalAddressSDNode>(Src.getOperand(0));

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -617,8 +617,14 @@ bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth,
617617
// operands on the new node are also disjoint.
618618
SDNodeFlags Flags(Op->getFlags().hasDisjoint() ? SDNodeFlags::Disjoint
619619
: SDNodeFlags::None);
620+
unsigned Opcode = Op.getOpcode();
621+
if (Opcode == ISD::PTRADD) {
622+
// It isn't a ptradd anymore if it doesn't operate on the entire
623+
// pointer.
624+
Opcode = ISD::ADD;
625+
}
620626
SDValue X = DAG.getNode(
621-
Op.getOpcode(), dl, SmallVT,
627+
Opcode, dl, SmallVT,
622628
DAG.getNode(ISD::TRUNCATE, dl, SmallVT, Op.getOperand(0)),
623629
DAG.getNode(ISD::TRUNCATE, dl, SmallVT, Op.getOperand(1)), Flags);
624630
assert(DemandedSize <= SmallVTBits && "Narrowed below demanded bits?");
@@ -2853,6 +2859,11 @@ bool TargetLowering::SimplifyDemandedBits(
28532859
return TLO.CombineTo(Op, And1);
28542860
}
28552861
[[fallthrough]];
2862+
case ISD::PTRADD:
2863+
if (Op.getOperand(0).getValueType() != Op.getOperand(1).getValueType())
2864+
break;
2865+
// PTRADD behaves like ADD if pointers are represented as integers.
2866+
[[fallthrough]];
28562867
case ISD::ADD:
28572868
case ISD::SUB: {
28582869
// Add, Sub, and Mul don't demand any bits in positions beyond that
@@ -2962,10 +2973,10 @@ bool TargetLowering::SimplifyDemandedBits(
29622973

29632974
if (Op.getOpcode() == ISD::MUL) {
29642975
Known = KnownBits::mul(KnownOp0, KnownOp1);
2965-
} else { // Op.getOpcode() is either ISD::ADD or ISD::SUB.
2976+
} else { // Op.getOpcode() is either ISD::ADD, ISD::PTRADD, or ISD::SUB.
29662977
Known = KnownBits::computeForAddSub(
2967-
Op.getOpcode() == ISD::ADD, Flags.hasNoSignedWrap(),
2968-
Flags.hasNoUnsignedWrap(), KnownOp0, KnownOp1);
2978+
Op->isAnyAdd(), Flags.hasNoSignedWrap(), Flags.hasNoUnsignedWrap(),
2979+
KnownOp0, KnownOp1);
29692980
}
29702981
break;
29712982
}
@@ -5608,7 +5619,7 @@ bool TargetLowering::isGAPlusOffset(SDNode *WN, const GlobalValue *&GA,
56085619
return true;
56095620
}
56105621

5611-
if (N->getOpcode() == ISD::ADD) {
5622+
if (N->isAnyAdd()) {
56125623
SDValue N1 = N->getOperand(0);
56135624
SDValue N2 = N->getOperand(1);
56145625
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
@@ -1449,7 +1449,7 @@ bool AMDGPUDAGToDAGISel::SelectMUBUF(SDValue Addr, SDValue &Ptr, SDValue &VAddr,
14491449
C1 = nullptr;
14501450
}
14511451

1452-
if (N0.getOpcode() == ISD::ADD) {
1452+
if (N0->isAnyAdd()) {
14531453
// (add N2, N3) -> addr64, or
14541454
// (add (add N2, N3), C1) -> addr64
14551455
SDValue N2 = N0.getOperand(0);
@@ -1899,7 +1899,7 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N,
18991899
}
19001900

19011901
// Match the variable offset.
1902-
if (Addr.getOpcode() == ISD::ADD) {
1902+
if (Addr->isAnyAdd()) {
19031903
LHS = Addr.getOperand(0);
19041904
RHS = Addr.getOperand(1);
19051905

@@ -2230,7 +2230,7 @@ bool AMDGPUDAGToDAGISel::SelectSMRDBaseOffset(SDValue Addr, SDValue &SBase,
22302230

22312231
SDValue N0, N1;
22322232
// Extract the base and offset if possible.
2233-
if (CurDAG->isBaseWithConstantOffset(Addr) || Addr.getOpcode() == ISD::ADD) {
2233+
if (CurDAG->isBaseWithConstantOffset(Addr) || Addr->isAnyAdd()) {
22342234
N0 = Addr.getOperand(0);
22352235
N1 = Addr.getOperand(1);
22362236
} 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
@@ -10477,7 +10477,7 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
1047710477
SDValue VOffset;
1047810478
// Try to split SAddr and VOffset. Global and LDS pointers share the same
1047910479
// immediate offset, so we cannot use a regular SelectGlobalSAddr().
10480-
if (Addr->isDivergent() && Addr.getOpcode() == ISD::ADD) {
10480+
if (Addr->isDivergent() && Addr->isAnyAdd()) {
1048110481
SDValue LHS = Addr.getOperand(0);
1048210482
SDValue RHS = Addr.getOperand(1);
1048310483

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

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

1203412033
const ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N1);
@@ -12067,6 +12066,8 @@ SDValue SITargetLowering::performSHLPtrCombine(SDNode *N, unsigned AddrSpace,
1206712066
N->getFlags().hasNoUnsignedWrap() &&
1206812067
(N0.getOpcode() == ISD::OR || N0->getFlags().hasNoUnsignedWrap()));
1206912068

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

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)