Skip to content

Commit b6ce6e5

Browse files
committed
Don't look through addrspacecast in GetPointerBaseWithConstantOffset
Pointers in different addrspaces can have different sizes, so it's not valid to look through addrspace cast calculating base and offset for a value. This is similar to D13008. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D24729 llvm-svn: 282612
1 parent 7f5866c commit b6ce6e5

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2848,9 +2848,14 @@ Value *llvm::GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
28482848
ByteOffset += GEPOffset;
28492849

28502850
Ptr = GEP->getPointerOperand();
2851-
} else if (Operator::getOpcode(Ptr) == Instruction::BitCast ||
2852-
Operator::getOpcode(Ptr) == Instruction::AddrSpaceCast) {
2851+
} else if (Operator::getOpcode(Ptr) == Instruction::BitCast) {
28532852
Ptr = cast<Operator>(Ptr)->getOperand(0);
2853+
} else if (AddrSpaceCastInst *ASCI = dyn_cast<AddrSpaceCastInst>(Ptr)) {
2854+
Value *SourcePtr = ASCI->getPointerOperand();
2855+
// Don't look through addrspace cast which changes pointer size
2856+
if (BitWidth != DL.getPointerTypeSizeInBits(SourcePtr->getType()))
2857+
break;
2858+
Ptr = SourcePtr;
28542859
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(Ptr)) {
28552860
if (GA->isInterposable())
28562861
break;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: opt < %s -default-data-layout="e-p:32:32:32-p1:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -basicaa -gvn -S -die | FileCheck %s
2+
3+
define i8 @coerce_offset0_addrspacecast(i32 %V, i32* %P) {
4+
store i32 %V, i32* %P
5+
6+
%P2 = addrspacecast i32* %P to i8 addrspace(1)*
7+
%P3 = getelementptr i8, i8 addrspace(1)* %P2, i32 2
8+
9+
%A = load i8, i8 addrspace(1)* %P3
10+
ret i8 %A
11+
; CHECK-LABEL: @coerce_offset0_addrspacecast(
12+
; CHECK-NOT: load
13+
; CHECK: ret i8
14+
}

llvm/test/Transforms/GVN/PRE/rle.ll

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -318,19 +318,6 @@ define i8 @coerce_offset0(i32 %V, i32* %P) {
318318
; CHECK: ret i8
319319
}
320320

321-
define i8 @coerce_offset0_addrspacecast(i32 %V, i32* %P) {
322-
store i32 %V, i32* %P
323-
324-
%P2 = addrspacecast i32* %P to i8 addrspace(1)*
325-
%P3 = getelementptr i8, i8 addrspace(1)* %P2, i32 2
326-
327-
%A = load i8, i8 addrspace(1)* %P3
328-
ret i8 %A
329-
; CHECK-LABEL: @coerce_offset0_addrspacecast(
330-
; CHECK-NOT: load
331-
; CHECK: ret i8
332-
}
333-
334321
;; non-local i32/float -> i8 load forwarding.
335322
define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) {
336323
%P2 = bitcast i32* %P to float*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: opt < %s -gvn -S | FileCheck %s
2+
target datalayout = "e-m:e-p:16:16-p1:32:16-i32:16-i64:16-n8:16"
3+
4+
; In cases where two address spaces do not have the same size pointer, the
5+
; input for the addrspacecast should not be used as a substitute for itself
6+
; when manipulating the pointer.
7+
8+
; Check that we don't hit the assert in this scenario
9+
define i8 @test(i32 %V, i32* %P) {
10+
; CHECK-LABEL: @test(
11+
; CHECK: load
12+
%P1 = getelementptr inbounds i32, i32* %P, i16 16
13+
14+
store i32 %V, i32* %P1
15+
16+
%P2 = addrspacecast i32* %P1 to i8 addrspace(1)*
17+
%P3 = getelementptr i8, i8 addrspace(1)* %P2, i32 2
18+
19+
%A = load i8, i8 addrspace(1)* %P3
20+
ret i8 %A
21+
}

0 commit comments

Comments
 (0)