[PATCH] SelectionDAG: Use the correct address space size for GEP instructions
Tom Stellard
tom at stellard.net
Tue Oct 15 11:12:42 PDT 2013
From: Tom Stellard <thomas.stellard at amd.com>
This fixes a crash in the SelectionDAGBuilder where GEP instructions
with a pointer to an array as its first argument would mix the pointer's
address space type with the default address space type while calculating
the offset for the array.
---
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 17 ++++++++++++++++-
test/CodeGen/R600/address-space.ll | 11 +++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 0cee3d7..7a5a4c9 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3234,6 +3234,22 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
// element which holds a pointer.
Type *Ty = I.getOperand(0)->getType()->getScalarType();
+ // As the loop below goes through the list of offsets, it also replaces Ty
+ // with the element type of Ty. For a gep like:
+ // [2 x [264 x i32]] addrspace(3)* @local.mem, i32 0, i32 1, i32 %index
+ // Ty will have the following values:
+ // Iteration 0: [2 x [264 x i32]] addrspace(3)*
+ // Iteration 1: [2 x [264 x i32]]
+ // Iteration 2: [264 x i32]
+ //
+ // Once we have descended into the element type of the pointer we lose the
+ // address space information, which we need in order to generate pointer
+ // arithmetic instructions with the correct types.
+ //
+ // We must cache the address space information here, so that it
+ // is not overwritten with 0 by non-pointer types.
+ uint32_t AS = 0;
+
for (GetElementPtrInst::const_op_iterator OI = I.op_begin()+1, E = I.op_end();
OI != E; ++OI) {
const Value *Idx = *OI;
@@ -3248,7 +3264,6 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
Ty = StTy->getElementType(Field);
} else {
- uint32_t AS = 0;
if (PointerType *PtrType = dyn_cast<PointerType>(Ty)) {
AS = PtrType->getAddressSpace();
}
diff --git a/test/CodeGen/R600/address-space.ll b/test/CodeGen/R600/address-space.ll
index 11289d2..d8e6c63 100644
--- a/test/CodeGen/R600/address-space.ll
+++ b/test/CodeGen/R600/address-space.ll
@@ -27,4 +27,15 @@ bb34:
unreachable
}
+; Test for a bug in SelectionDAGBuilder that were it was using the incorrect
+; address space size for pointers to arrays
+ at local.mem = internal addrspace(3) unnamed_addr global [2 x [264 x i32]] zeroinitializer, align 16
+
+; CHECK: DS_WRITE_B32 0
+define void @gep_array(i32 %index) {
+entry:
+ %0 = getelementptr [2 x [264 x i32]] addrspace(3)* @local.mem, i32 0, i32 1, i32 %index
+ store i32 4, i32 addrspace(3)* %0
+ ret void
+}
--
1.8.1.5
More information about the llvm-commits
mailing list