1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

Remove handling of AddrSpaceCast in stripAndAccumulateInBoundsConstantOffsets

Patch by: simoncook

Unlike BitCasts, AddrSpaceCasts do not always produce an output the same size as its input, which was previously assumed. This fixes cases where two address spaces do not have the same size pointer, as an assertion failure would occur when trying to prove deferenceability.  LoopUnswitch is used in the particular test, but LICM also exhibits the same problem.

Differential Revision: http://reviews.llvm.org/D13008

llvm-svn: 248422
This commit is contained in:
Philip Reames 2015-09-23 19:48:43 +00:00
parent 05c92790cf
commit daa3d37196
2 changed files with 29 additions and 2 deletions

View File

@ -490,8 +490,7 @@ Value *Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL,
return V;
Offset = GEPOffset;
V = GEP->getPointerOperand();
} else if (Operator::getOpcode(V) == Instruction::BitCast ||
Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
V = cast<Operator>(V)->getOperand(0);
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
V = GA->getAliasee();

View File

@ -0,0 +1,28 @@
; RUN: opt < %s -loop-unswitch -S | FileCheck %s
; In cases where two address spaces do not have the same size pointer, the
; input for the addrspacecast should not be used as a substitute for itself
; when manipulating the pointer.
target datalayout = "e-m:e-p:16:16-p1:32:16-i32:16-i64:16-n8:16"
define void @foo() {
; CHECK-LABEL: @foo
entry:
%arrayidx.i1 = getelementptr inbounds i16, i16* undef, i16 undef
%arrayidx.i = addrspacecast i16* %arrayidx.i1 to i16 addrspace(1)*
br i1 undef, label %for.body.i, label %bar.exit
for.body.i: ; preds = %for.body.i, %entry
; When we call makeLoopInvariant (i.e. trivial LICM) on this load, it
; will try to find the base object to prove deferenceability. If we look
; through the addrspacecast, we'll fail an assertion about bitwidths matching
; CHECK-LABEL: for.body.i
; CHECK: %0 = load i16, i16 addrspace(1)* %arrayidx.i, align 2
%0 = load i16, i16 addrspace(1)* %arrayidx.i, align 2
%cmp1.i = icmp eq i16 %0, 0
br i1 %cmp1.i, label %bar.exit, label %for.body.i
bar.exit: ; preds = %for.body.i, %entry
ret void
}