Skip to content

Commit 86f2e09

Browse files
authored
[AMDGPU] Tweak handling of GlobalAddress operands in SI_PC_ADD_REL_OFFSET (#70960)
When SI_PC_ADD_REL_OFFSET is expanded to S_GETPC/S_ADD/S_ADDC, the GlobalAddress operands have to be adjusted by 4 or 12 bytes to account for the offset from the end of the S_GETPC instruction to the literal operands. Do this all in SIInstrInfo::expandPostRAPseudo instead of duplicating the adjustment code in both AMDGPULegalizerInfo and SITargetLowering. NFCI.
1 parent 64d5da6 commit 86f2e09

File tree

8 files changed

+72
-81
lines changed

8 files changed

+72
-81
lines changed

llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,15 +2736,6 @@ bool AMDGPULegalizerInfo::buildPCRelGlobalAddress(Register DstReg, LLT PtrTy,
27362736
// $symbol@*@hi with lower 32 bits and higher 32 bits of a literal constant,
27372737
// which is a 64-bit pc-relative offset from the encoding of the $symbol
27382738
// operand to the global variable.
2739-
//
2740-
// What we want here is an offset from the value returned by s_getpc
2741-
// (which is the address of the s_add_u32 instruction) to the global
2742-
// variable, but since the encoding of $symbol starts 4 bytes after the start
2743-
// of the s_add_u32 instruction, we end up with an offset that is 4 bytes too
2744-
// small. This requires us to add 4 to the global variable offset in order to
2745-
// compute the correct address. Similarly for the s_addc_u32 instruction, the
2746-
// encoding of $symbol starts 12 bytes after the start of the s_add_u32
2747-
// instruction.
27482739

27492740
LLT ConstPtrTy = LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS, 64);
27502741

@@ -2754,11 +2745,11 @@ bool AMDGPULegalizerInfo::buildPCRelGlobalAddress(Register DstReg, LLT PtrTy,
27542745
MachineInstrBuilder MIB = B.buildInstr(AMDGPU::SI_PC_ADD_REL_OFFSET)
27552746
.addDef(PCReg);
27562747

2757-
MIB.addGlobalAddress(GV, Offset + 4, GAFlags);
2748+
MIB.addGlobalAddress(GV, Offset, GAFlags);
27582749
if (GAFlags == SIInstrInfo::MO_NONE)
27592750
MIB.addImm(0);
27602751
else
2761-
MIB.addGlobalAddress(GV, Offset + 12, GAFlags + 1);
2752+
MIB.addGlobalAddress(GV, Offset, GAFlags + 1);
27622753

27632754
if (!B.getMRI()->getRegClassOrNull(PCReg))
27642755
B.getMRI()->setRegClass(PCReg, &AMDGPU::SReg_64RegClass);

llvm/lib/Target/AMDGPU/SIISelLowering.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6725,24 +6725,12 @@ buildPCRelGlobalAddress(SelectionDAG &DAG, const GlobalValue *GV,
67256725
// $symbol@*@hi with lower 32 bits and higher 32 bits of a literal constant,
67266726
// which is a 64-bit pc-relative offset from the encoding of the $symbol
67276727
// operand to the global variable.
6728-
//
6729-
// What we want here is an offset from the value returned by s_getpc
6730-
// (which is the address of the s_add_u32 instruction) to the global
6731-
// variable, but since the encoding of $symbol starts 4 bytes after the start
6732-
// of the s_add_u32 instruction, we end up with an offset that is 4 bytes too
6733-
// small. This requires us to add 4 to the global variable offset in order to
6734-
// compute the correct address. Similarly for the s_addc_u32 instruction, the
6735-
// encoding of $symbol starts 12 bytes after the start of the s_add_u32
6736-
// instruction.
6737-
SDValue PtrLo =
6738-
DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset + 4, GAFlags);
6728+
SDValue PtrLo = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset, GAFlags);
67396729
SDValue PtrHi;
6740-
if (GAFlags == SIInstrInfo::MO_NONE) {
6730+
if (GAFlags == SIInstrInfo::MO_NONE)
67416731
PtrHi = DAG.getTargetConstant(0, DL, MVT::i32);
6742-
} else {
6743-
PtrHi =
6744-
DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset + 12, GAFlags + 1);
6745-
}
6732+
else
6733+
PtrHi = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, Offset, GAFlags + 1);
67466734
return DAG.getNode(AMDGPUISD::PC_ADD_REL_OFFSET, DL, PtrVT, PtrLo, PtrHi);
67476735
}
67486736

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,21 +2388,33 @@ bool SIInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
23882388
Register Reg = MI.getOperand(0).getReg();
23892389
Register RegLo = RI.getSubReg(Reg, AMDGPU::sub0);
23902390
Register RegHi = RI.getSubReg(Reg, AMDGPU::sub1);
2391+
MachineOperand OpLo = MI.getOperand(1);
2392+
MachineOperand OpHi = MI.getOperand(2);
23912393

23922394
// Create a bundle so these instructions won't be re-ordered by the
23932395
// post-RA scheduler.
23942396
MIBundleBuilder Bundler(MBB, MI);
23952397
Bundler.append(BuildMI(MF, DL, get(AMDGPU::S_GETPC_B64), Reg));
23962398

2397-
// Add 32-bit offset from this instruction to the start of the
2398-
// constant data.
2399-
Bundler.append(BuildMI(MF, DL, get(AMDGPU::S_ADD_U32), RegLo)
2400-
.addReg(RegLo)
2401-
.add(MI.getOperand(1)));
2402-
2399+
// What we want here is an offset from the value returned by s_getpc (which
2400+
// is the address of the s_add_u32 instruction) to the global variable, but
2401+
// since the encoding of $symbol starts 4 bytes after the start of the
2402+
// s_add_u32 instruction, we end up with an offset that is 4 bytes too
2403+
// small. This requires us to add 4 to the global variable offset in order
2404+
// to compute the correct address. Similarly for the s_addc_u32 instruction,
2405+
// the encoding of $symbol starts 12 bytes after the start of the s_add_u32
2406+
// instruction.
2407+
2408+
if (OpLo.isGlobal())
2409+
OpLo.setOffset(OpLo.getOffset() + 4);
2410+
Bundler.append(
2411+
BuildMI(MF, DL, get(AMDGPU::S_ADD_U32), RegLo).addReg(RegLo).add(OpLo));
2412+
2413+
if (OpHi.isGlobal())
2414+
OpHi.setOffset(OpHi.getOffset() + 12);
24032415
Bundler.append(BuildMI(MF, DL, get(AMDGPU::S_ADDC_U32), RegHi)
24042416
.addReg(RegHi)
2405-
.add(MI.getOperand(2)));
2417+
.add(OpHi));
24062418

24072419
finalizeBundle(MBB, Bundler.begin());
24082420

llvm/test/CodeGen/AMDGPU/GlobalISel/dropped_debug_info_assert.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ define amdgpu_kernel void @call_debug_loc() {
4545
; CHECK-NEXT: $sgpr14 = COPY [[COPY15]], debug-location !6
4646
; CHECK-NEXT: $sgpr15 = COPY [[DEF]], debug-location !6
4747
; CHECK-NEXT: $vgpr31 = COPY [[V_OR3_B32_e64_]], debug-location !6
48-
; CHECK-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @callee + 4, target-flags(amdgpu-gotprel32-hi) @callee + 12, implicit-def $scc, debug-location !6
48+
; CHECK-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @callee, target-flags(amdgpu-gotprel32-hi) @callee, implicit-def $scc, debug-location !6
4949
; CHECK-NEXT: [[S_LOAD_DWORDX2_IMM:%[0-9]+]]:sreg_64_xexec = S_LOAD_DWORDX2_IMM [[SI_PC_ADD_REL_OFFSET]], 0, 0, debug-location !6 :: (dereferenceable invariant load (p0) from got, addrspace 4)
5050
; CHECK-NEXT: $sgpr30_sgpr31 = noconvergent SI_CALL [[S_LOAD_DWORDX2_IMM]], @callee, csr_amdgpu, implicit $sgpr0_sgpr1_sgpr2_sgpr3, implicit $sgpr4_sgpr5, implicit $sgpr6_sgpr7, implicit $sgpr8_sgpr9, implicit $sgpr10_sgpr11, implicit $sgpr12, implicit $sgpr13, implicit $sgpr14, implicit $sgpr15, implicit $vgpr31, debug-location !6
5151
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $scc, debug-location !6

llvm/test/CodeGen/AMDGPU/GlobalISel/global-value.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define ptr addrspace(4) @external_constant_got() {
1717

1818
; GCN-LABEL: name: external_constant_got
1919
; GCN: bb.1 (%ir-block.0):
20-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_constant + 4, target-flags(amdgpu-gotprel32-hi) @external_constant + 12, implicit-def $scc
20+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_constant, target-flags(amdgpu-gotprel32-hi) @external_constant, implicit-def $scc
2121
; GCN-NEXT: [[LOAD:%[0-9]+]]:_(p4) = G_LOAD [[SI_PC_ADD_REL_OFFSET]](p4) :: (dereferenceable invariant load (p4) from got, addrspace 4)
2222
; GCN-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[LOAD]](p4)
2323
; GCN-NEXT: $vgpr0 = COPY [[UV]](s32)
@@ -38,7 +38,7 @@ define ptr addrspace(1) @external_global_got() {
3838

3939
; GCN-LABEL: name: external_global_got
4040
; GCN: bb.1 (%ir-block.0):
41-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_global + 4, target-flags(amdgpu-gotprel32-hi) @external_global + 12, implicit-def $scc
41+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_global, target-flags(amdgpu-gotprel32-hi) @external_global, implicit-def $scc
4242
; GCN-NEXT: [[LOAD:%[0-9]+]]:_(p1) = G_LOAD [[SI_PC_ADD_REL_OFFSET]](p4) :: (dereferenceable invariant load (p1) from got, addrspace 4)
4343
; GCN-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[LOAD]](p1)
4444
; GCN-NEXT: $vgpr0 = COPY [[UV]](s32)
@@ -59,7 +59,7 @@ define ptr addrspace(999) @external_other_got() {
5959

6060
; GCN-LABEL: name: external_other_got
6161
; GCN: bb.1 (%ir-block.0):
62-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_other + 4, target-flags(amdgpu-gotprel32-hi) @external_other + 12, implicit-def $scc
62+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_other, target-flags(amdgpu-gotprel32-hi) @external_other, implicit-def $scc
6363
; GCN-NEXT: [[LOAD:%[0-9]+]]:_(p999) = G_LOAD [[SI_PC_ADD_REL_OFFSET]](p4) :: (dereferenceable invariant load (p999) from got, addrspace 4)
6464
; GCN-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[LOAD]](p999)
6565
; GCN-NEXT: $vgpr0 = COPY [[UV]](s32)
@@ -80,7 +80,7 @@ define ptr addrspace(4) @internal_constant_pcrel() {
8080

8181
; GCN-LABEL: name: internal_constant_pcrel
8282
; GCN: bb.1 (%ir-block.0):
83-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_constant + 4, target-flags(amdgpu-rel32-hi) @internal_constant + 12, implicit-def $scc
83+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_constant, target-flags(amdgpu-rel32-hi) @internal_constant, implicit-def $scc
8484
; GCN-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[SI_PC_ADD_REL_OFFSET]](p4)
8585
; GCN-NEXT: $vgpr0 = COPY [[UV]](s32)
8686
; GCN-NEXT: $vgpr1 = COPY [[UV1]](s32)
@@ -100,7 +100,7 @@ define ptr addrspace(1) @internal_global_pcrel() {
100100

101101
; GCN-LABEL: name: internal_global_pcrel
102102
; GCN: bb.1 (%ir-block.0):
103-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p1) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_global + 4, target-flags(amdgpu-rel32-hi) @internal_global + 12, implicit-def $scc
103+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p1) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_global, target-flags(amdgpu-rel32-hi) @internal_global, implicit-def $scc
104104
; GCN-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[SI_PC_ADD_REL_OFFSET]](p1)
105105
; GCN-NEXT: $vgpr0 = COPY [[UV]](s32)
106106
; GCN-NEXT: $vgpr1 = COPY [[UV1]](s32)
@@ -120,7 +120,7 @@ define ptr addrspace(999) @internal_other_pcrel() {
120120

121121
; GCN-LABEL: name: internal_other_pcrel
122122
; GCN: bb.1 (%ir-block.0):
123-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p999) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_other + 4, target-flags(amdgpu-rel32-hi) @internal_other + 12, implicit-def $scc
123+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p999) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_other, target-flags(amdgpu-rel32-hi) @internal_other, implicit-def $scc
124124
; GCN-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[SI_PC_ADD_REL_OFFSET]](p999)
125125
; GCN-NEXT: $vgpr0 = COPY [[UV]](s32)
126126
; GCN-NEXT: $vgpr1 = COPY [[UV1]](s32)
@@ -140,7 +140,7 @@ define ptr addrspace(6) @external_constant32_got() {
140140

141141
; GCN-LABEL: name: external_constant32_got
142142
; GCN: bb.1 (%ir-block.0):
143-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_constant32 + 4, target-flags(amdgpu-gotprel32-hi) @external_constant32 + 12, implicit-def $scc
143+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @external_constant32, target-flags(amdgpu-gotprel32-hi) @external_constant32, implicit-def $scc
144144
; GCN-NEXT: [[LOAD:%[0-9]+]]:_(p4) = G_LOAD [[SI_PC_ADD_REL_OFFSET]](p4) :: (dereferenceable invariant load (p4) from got, addrspace 4)
145145
; GCN-NEXT: [[EXTRACT:%[0-9]+]]:_(p6) = G_EXTRACT [[LOAD]](p4), 0
146146
; GCN-NEXT: $vgpr0 = COPY [[EXTRACT]](p6)
@@ -158,7 +158,7 @@ define ptr addrspace(6) @internal_constant32_pcrel() {
158158

159159
; GCN-LABEL: name: internal_constant32_pcrel
160160
; GCN: bb.1 (%ir-block.0):
161-
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_constant32 + 4, target-flags(amdgpu-rel32-hi) @internal_constant32 + 12, implicit-def $scc
161+
; GCN-NEXT: [[SI_PC_ADD_REL_OFFSET:%[0-9]+]]:sreg_64(p4) = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @internal_constant32, target-flags(amdgpu-rel32-hi) @internal_constant32, implicit-def $scc
162162
; GCN-NEXT: [[EXTRACT:%[0-9]+]]:_(p6) = G_EXTRACT [[SI_PC_ADD_REL_OFFSET]](p4), 0
163163
; GCN-NEXT: $vgpr0 = COPY [[EXTRACT]](p6)
164164
; GCN-NEXT: SI_RETURN implicit $vgpr0

llvm/test/CodeGen/AMDGPU/amdgcn-load-offset-from-reg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ define amdgpu_cs void @test_load_zext(i32 inreg %0, i32 inreg %1, i32 inreg %res
3131
; Make sure we match constant bases with register offests, in which case
3232
; the base may be the RHS operand of the load in SDAG.
3333
; GCN-LABEL: name: test_complex_reg_offset
34-
; GCN-DAG: %[[BASE:.*]]:sreg_64 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @0 + 4,
34+
; GCN-DAG: %[[BASE:.*]]:sreg_64 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-rel32-lo) @0,
3535
; SDAG-DAG: %[[OFFSET:.*]]:sreg_32 = nuw nsw S_LSHL_B32
3636
; GISEL-DAG: %[[OFFSET:.*]]:sreg_32 = S_LSHL_B32
3737
; SDAG: S_LOAD_DWORD_SGPR_IMM killed %[[BASE]], killed %[[OFFSET]], 0, 0

llvm/test/CodeGen/AMDGPU/branch-folding-implicit-def-subreg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ define amdgpu_kernel void @f1(ptr addrspace(1) %arg, ptr addrspace(1) %arg1, i64
201201
; GFX90A-NEXT: {{ $}}
202202
; GFX90A-NEXT: renamable $sgpr8 = S_ADD_U32 renamable $sgpr8, 48, implicit-def $scc
203203
; GFX90A-NEXT: renamable $sgpr9 = S_ADDC_U32 killed renamable $sgpr9, 0, implicit-def dead $scc, implicit killed $scc
204-
; GFX90A-NEXT: renamable $sgpr12_sgpr13 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @f2 + 4, target-flags(amdgpu-gotprel32-hi) @f2 + 12, implicit-def dead $scc
204+
; GFX90A-NEXT: renamable $sgpr12_sgpr13 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @f2, target-flags(amdgpu-gotprel32-hi) @f2, implicit-def dead $scc
205205
; GFX90A-NEXT: renamable $sgpr18_sgpr19 = S_LOAD_DWORDX2_IMM killed renamable $sgpr12_sgpr13, 0, 0 :: (dereferenceable invariant load (s64) from got, addrspace 4)
206206
; GFX90A-NEXT: $sgpr12 = COPY killed renamable $sgpr14
207207
; GFX90A-NEXT: $sgpr13 = COPY killed renamable $sgpr15

0 commit comments

Comments
 (0)