summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikael Holmen <mikael.holmen@ericsson.com>2017-02-14 06:37:42 +0000
committerMikael Holmen <mikael.holmen@ericsson.com>2017-02-14 06:37:42 +0000
commitece84cd10c68f98c18bda52be4e178b2493f7ece (patch)
tree09182c3b15a47b06906010e95f6d6c6f1d861dc7
parent758cf9da3748b5ec3d0a9cae93bf2265bbe5404f (diff)
downloadbcm5719-llvm-ece84cd10c68f98c18bda52be4e178b2493f7ece.tar.gz
bcm5719-llvm-ece84cd10c68f98c18bda52be4e178b2493f7ece.zip
[LSR] Pointers with different address spaces are considered incompatible.
Summary: Function isCompatibleIVType is already used as a guard before the call to SE.getMinusSCEV(OperExpr, PrevExpr); in LSRInstance::ChainInstruction. getMinusSCEV requires the expressions to be of the same type, so we now consider two pointers with different address spaces to be incompatible, since it is possible that the pointers in fact have different sizes. Reviewers: qcolombet, eli.friedman Reviewed By: qcolombet Subscribers: nhaehnle, Ka-Ka, llvm-commits, mzolotukhin Differential Revision: https://reviews.llvm.org/D29885 llvm-svn: 295033
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp7
-rw-r--r--llvm/test/Transforms/LoopStrengthReduce/AMDGPU/different-addrspace-crash.ll31
2 files changed, 37 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index a59d901d76e..baef7b9a196 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -2559,7 +2559,12 @@ static Value *getWideOperand(Value *Oper) {
static bool isCompatibleIVType(Value *LVal, Value *RVal) {
Type *LType = LVal->getType();
Type *RType = RVal->getType();
- return (LType == RType) || (LType->isPointerTy() && RType->isPointerTy());
+ return (LType == RType) || (LType->isPointerTy() && RType->isPointerTy() &&
+ // Different address spaces means (possibly)
+ // different types of the pointer implementation,
+ // e.g. i16 vs i32 so disallow that.
+ (LType->getPointerAddressSpace() ==
+ RType->getPointerAddressSpace()));
}
/// Return an approximation of this SCEV expression's "base", or NULL for any
diff --git a/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/different-addrspace-crash.ll b/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/different-addrspace-crash.ll
new file mode 100644
index 00000000000..89b62632cac
--- /dev/null
+++ b/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/different-addrspace-crash.ll
@@ -0,0 +1,31 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
+target triple = "amdgcn--"
+
+; We need to compile this for a target where we have different address spaces,
+; and where pointers in those address spaces have different size.
+; E.g. for amdgcn-- pointers in address space 0 are 32 bits and pointers in
+; address space 1 are 64 bits.
+
+; We shouldn't crash. Check that we get a loop with the two stores.
+;CHECK-LABEL: foo:
+;CHECK: [[LOOP_LABEL:BB[0-9]+_[0-9]+]]:
+;CHECK: buffer_store_dword
+;CHECK: buffer_store_dword
+;CHECK: s_branch [[LOOP_LABEL]]
+
+define void @foo() {
+entry:
+ br label %loop
+
+loop:
+ %idx0 = phi i32 [ %next_idx0, %loop ], [ 0, %entry ]
+ %0 = getelementptr inbounds i32, i32* null, i32 %idx0
+ %1 = getelementptr inbounds i32, i32 addrspace(1)* null, i32 %idx0
+ store i32 1, i32* %0
+ store i32 7, i32 addrspace(1)* %1
+ %next_idx0 = add nuw nsw i32 %idx0, 1
+ br label %loop
+}
+
OpenPOWER on IntegriCloud