diff options
-rw-r--r-- | llvm/lib/Target/DirectX/DXILFlattenArrays.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/DirectX/flatten-array.ll | 22 |
2 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp b/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp index ce43645..f0e2e78 100644 --- a/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp +++ b/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp @@ -343,6 +343,16 @@ bool DXILFlattenArraysVisitor::visitGetElementPtrInst(GetElementPtrInst &GEP) { Info.RootFlattenedArrayType, Info.RootPointerOperand, {ZeroIndex, FlattenedIndex}, GEP.getName(), GEP.getNoWrapFlags()); + // If the pointer operand is a global variable and all indices are 0, + // IRBuilder::CreateGEP will return the global variable instead of creating + // a GEP instruction or GEP ConstantExpr. In this case we have to create and + // insert our own GEP instruction. + if (!isa<GEPOperator>(NewGEP)) + NewGEP = GetElementPtrInst::Create( + Info.RootFlattenedArrayType, Info.RootPointerOperand, + {ZeroIndex, FlattenedIndex}, GEP.getNoWrapFlags(), GEP.getName(), + Builder.GetInsertPoint()); + // Replace the current GEP with the new GEP. Store GEPInfo into the map // for later use in case this GEP was not the end of the chain GEPChainInfoMap.insert({cast<GEPOperator>(NewGEP), std::move(Info)}); diff --git a/llvm/test/CodeGen/DirectX/flatten-array.ll b/llvm/test/CodeGen/DirectX/flatten-array.ll index 1376a1d..a2e1055 100644 --- a/llvm/test/CodeGen/DirectX/flatten-array.ll +++ b/llvm/test/CodeGen/DirectX/flatten-array.ll @@ -218,6 +218,28 @@ define void @two_index_gep_const() { ret void } +define void @zero_index_global() { + ; CHECK-LABEL: define void @zero_index_global( + ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw [4 x float], ptr addrspace(3) @g.1dim, i32 0, i32 0 + ; CHECK-NEXT: load float, ptr addrspace(3) [[GEP]], align 4 + ; CHECK-NEXT: ret void + %1 = getelementptr inbounds nuw [2 x [2 x float]], ptr addrspace(3) @g, i32 0, i32 0, i32 0 + %2 = load float, ptr addrspace(3) %1, align 4 + ret void +} + +; Note: A ConstantExpr GEP with all 0 indices is equivalent to the pointer +; operand of the GEP. Therefore the visitLoadInst will not see the pointer operand +; as a ConstantExpr GEP and will not create a GEP instruction to be visited. +; The later dxil-legalize pass will insert a GEP in this instance. +define void @zero_index_global_const() { + ; CHECK-LABEL: define void @zero_index_global_const( + ; CHECK-NEXT: load float, ptr addrspace(3) @g.1dim, align 4 + ; CHECK-NEXT: ret void + %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 + ret void +} + define void @gep_4d_index_test() { ; CHECK-LABEL: gep_4d_index_test ; CHECK: [[a:%.*]] = alloca [16 x i32], align 4 |