Skip to content

Commit 286252e

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 7c9ac3c commit 286252e

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
@@ -615,8 +615,14 @@ bool TargetLowering::ShrinkDemandedOp(SDValue Op, unsigned BitWidth,
615615
// operands on the new node are also disjoint.
616616
SDNodeFlags Flags(Op->getFlags().hasDisjoint() ? SDNodeFlags::Disjoint
617617
: SDNodeFlags::None);
618+
unsigned Opcode = Op.getOpcode();
619+
if (Opcode == ISD::PTRADD) {
620+
// It isn't a ptradd anymore if it doesn't operate on the entire
621+
// pointer.
622+
Opcode = ISD::ADD;
623+
}
618624
SDValue X = DAG.getNode(
619-
Op.getOpcode(), dl, SmallVT,
625+
Opcode, dl, SmallVT,
620626
DAG.getNode(ISD::TRUNCATE, dl, SmallVT, Op.getOperand(0)),
621627
DAG.getNode(ISD::TRUNCATE, dl, SmallVT, Op.getOperand(1)), Flags);
622628
assert(DemandedSize <= SmallVTBits && "Narrowed below demanded bits?");
@@ -2851,6 +2857,11 @@ bool TargetLowering::SimplifyDemandedBits(
28512857
return TLO.CombineTo(Op, And1);
28522858
}
28532859
[[fallthrough]];
2860+
case ISD::PTRADD:
2861+
if (Op.getOperand(0).getValueType() != Op.getOperand(1).getValueType())
2862+
break;
2863+
// PTRADD behaves like ADD if pointers are represented as integers.
2864+
[[fallthrough]];
28542865
case ISD::ADD:
28552866
case ISD::SUB: {
28562867
// Add, Sub, and Mul don't demand any bits in positions beyond that
@@ -2960,10 +2971,10 @@ bool TargetLowering::SimplifyDemandedBits(
29602971

29612972
if (Op.getOpcode() == ISD::MUL) {
29622973
Known = KnownBits::mul(KnownOp0, KnownOp1);
2963-
} else { // Op.getOpcode() is either ISD::ADD or ISD::SUB.
2974+
} else { // Op.getOpcode() is either ISD::ADD, ISD::PTRADD, or ISD::SUB.
29642975
Known = KnownBits::computeForAddSub(
2965-
Op.getOpcode() == ISD::ADD, Flags.hasNoSignedWrap(),
2966-
Flags.hasNoUnsignedWrap(), KnownOp0, KnownOp1);
2976+
Op->isAnyAdd(), Flags.hasNoSignedWrap(), Flags.hasNoUnsignedWrap(),
2977+
KnownOp0, KnownOp1);
29672978
}
29682979
break;
29692980
}
@@ -5593,7 +5604,7 @@ bool TargetLowering::isGAPlusOffset(SDNode *WN, const GlobalValue *&GA,
55935604
return true;
55945605
}
55955606

5596-
if (N->getOpcode() == ISD::ADD) {
5607+
if (N->isAnyAdd()) {
55975608
SDValue N1 = N->getOperand(0);
55985609
SDValue N2 = N->getOperand(1);
55995610
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
@@ -10488,7 +10488,7 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
1048810488
SDValue VOffset;
1048910489
// Try to split SAddr and VOffset. Global and LDS pointers share the same
1049010490
// immediate offset, so we cannot use a regular SelectGlobalSAddr().
10491-
if (Addr->isDivergent() && Addr.getOpcode() == ISD::ADD) {
10491+
if (Addr->isDivergent() && Addr->isAnyAdd()) {
1049210492
SDValue LHS = Addr.getOperand(0);
1049310493
SDValue RHS = Addr.getOperand(1);
1049410494

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

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

1204512044
const ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N1);
@@ -12078,6 +12077,8 @@ SDValue SITargetLowering::performSHLPtrCombine(SDNode *N, unsigned AddrSpace,
1207812077
N->getFlags().hasNoUnsignedWrap() &&
1207912078
(N0.getOpcode() == ISD::OR || N0->getFlags().hasNoUnsignedWrap()));
1208012079

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

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)