Skip to content

Commit fae8df2

Browse files
authored
[DirectX] Fix GEP flattening with 0-indexed GEPs on global variables (#149211)
Fixes #149179 The issue is that `Builder.CreateGEP` does not return a GEP Instruction or GEP ContantExpr when the pointer operand is a global variable and all indices are constant zeroes. This PR ensures that a GEP instruction is created if `Builder.CreateGEP` did not return a GEP.
1 parent 689e958 commit fae8df2

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

llvm/lib/Target/DirectX/DXILFlattenArrays.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,16 @@ bool DXILFlattenArraysVisitor::visitGetElementPtrInst(GetElementPtrInst &GEP) {
343343
Info.RootFlattenedArrayType, Info.RootPointerOperand,
344344
{ZeroIndex, FlattenedIndex}, GEP.getName(), GEP.getNoWrapFlags());
345345

346+
// If the pointer operand is a global variable and all indices are 0,
347+
// IRBuilder::CreateGEP will return the global variable instead of creating
348+
// a GEP instruction or GEP ConstantExpr. In this case we have to create and
349+
// insert our own GEP instruction.
350+
if (!isa<GEPOperator>(NewGEP))
351+
NewGEP = GetElementPtrInst::Create(
352+
Info.RootFlattenedArrayType, Info.RootPointerOperand,
353+
{ZeroIndex, FlattenedIndex}, GEP.getNoWrapFlags(), GEP.getName(),
354+
Builder.GetInsertPoint());
355+
346356
// Replace the current GEP with the new GEP. Store GEPInfo into the map
347357
// for later use in case this GEP was not the end of the chain
348358
GEPChainInfoMap.insert({cast<GEPOperator>(NewGEP), std::move(Info)});

llvm/test/CodeGen/DirectX/flatten-array.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,28 @@ define void @two_index_gep_const() {
218218
ret void
219219
}
220220

221+
define void @zero_index_global() {
222+
; CHECK-LABEL: define void @zero_index_global(
223+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [4 x float], ptr addrspace(3) @g.1dim, i32 0, i32 0
224+
; CHECK-NEXT: load float, ptr addrspace(3) [[GEP]], align 4
225+
; CHECK-NEXT: ret void
226+
%1 = getelementptr inbounds nuw [2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 0, i32 0
227+
%2 = load float, ptr addrspace(3) %1, align 4
228+
ret void
229+
}
230+
231+
; Note: A ConstantExpr GEP with all 0 indices is equivalent to the pointer
232+
; operand of the GEP. Therefore the visitLoadInst will not see the pointer operand
233+
; as a ConstantExpr GEP and will not create a GEP instruction to be visited.
234+
; The later dxil-legalize pass will insert a GEP in this instance.
235+
define void @zero_index_global_const() {
236+
; CHECK-LABEL: define void @zero_index_global_const(
237+
; CHECK-NEXT: load float, ptr addrspace(3) @g.1dim, align 4
238+
; CHECK-NEXT: ret void
239+
%1 = load float, ptr addrspace(3) getelementptr inbounds nuw ([2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 0, i32 0), align 4
240+
ret void
241+
}
242+
221243
define void @gep_4d_index_test() {
222244
; CHECK-LABEL: gep_4d_index_test
223245
; CHECK: [[a:%.*]] = alloca [16 x i32], align 4

0 commit comments

Comments
 (0)