Skip to content

Commit 0af4aa9

Browse files
author
Richard Osborne
committedMar 25, 2014
[InstCombine] Don't fold bitcast into store if it would need addrspacecast
Summary: Previously the code didn't check if the before and after types for the store were pointers to different address spaces. This resulted in instcombine using a bitcast to convert between pointers to different address spaces, causing an assertion due to the invalid cast. It is not be appropriate to use addrspacecast this case because it is not guaranteed to be a no-op cast. Instead bail out and do not do the transformation. CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D3117 llvm-svn: 204733
1 parent 9805ec4 commit 0af4aa9

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed
 

‎llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -508,15 +508,27 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
508508
if (!SrcPTy->isIntegerTy() && !SrcPTy->isPointerTy())
509509
return 0;
510510

511-
// If the pointers point into different address spaces or if they point to
512-
// values with different sizes, we can't do the transformation.
511+
// If the pointers point into different address spaces don't do the
512+
// transformation.
513+
if (SrcTy->getAddressSpace() !=
514+
cast<PointerType>(CI->getType())->getAddressSpace())
515+
return 0;
516+
517+
// If the pointers point to values of different sizes don't do the
518+
// transformation.
513519
if (!IC.getDataLayout() ||
514-
SrcTy->getAddressSpace() !=
515-
cast<PointerType>(CI->getType())->getAddressSpace() ||
516520
IC.getDataLayout()->getTypeSizeInBits(SrcPTy) !=
517521
IC.getDataLayout()->getTypeSizeInBits(DestPTy))
518522
return 0;
519523

524+
// If the pointers point to pointers to different address spaces don't do the
525+
// transformation. It is not safe to introduce an addrspacecast instruction in
526+
// this case since, depending on the target, addrspacecast may not be a no-op
527+
// cast.
528+
if (SrcPTy->isPointerTy() && DestPTy->isPointerTy() &&
529+
SrcPTy->getPointerAddressSpace() != DestPTy->getPointerAddressSpace())
530+
return 0;
531+
520532
// Okay, we are casting from one integer or pointer type to another of
521533
// the same size. Instead of casting the pointer before
522534
// the store, cast the value to be stored.

‎llvm/test/Transforms/InstCombine/bitcast-store.ll

+16-2
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,33 @@
33
; Instcombine should preserve metadata and alignment while
44
; folding a bitcast into a store.
55

6-
; CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 16, !tag !0
7-
86
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
97

108
%struct.A = type { i32 (...)** }
119

1210
@G = external constant [5 x i8*]
1311

12+
; CHECK-LABEL: @foo
13+
; CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 16, !tag !0
1414
define void @foo(%struct.A* %a) nounwind {
1515
entry:
1616
%0 = bitcast %struct.A* %a to i8***
1717
store i8** getelementptr inbounds ([5 x i8*]* @G, i64 0, i64 2), i8*** %0, align 16, !tag !0
1818
ret void
1919
}
2020

21+
; Check instcombine doesn't try and fold the following bitcast into the store.
22+
; This transformation would not be safe since we would need to use addrspacecast
23+
; and addrspacecast is not guaranteed to be a no-op cast.
24+
25+
; CHECK-LABEL: @bar
26+
; CHECK: %cast = bitcast i8** %b to i8 addrspace(1)**
27+
; CHECK: store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
28+
define void @bar(i8 addrspace(1)* %a, i8** %b) nounwind {
29+
entry:
30+
%cast = bitcast i8** %b to i8 addrspace(1)**
31+
store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
32+
ret void
33+
}
34+
2135
!0 = metadata !{metadata !"hello"}

0 commit comments

Comments
 (0)
Please sign in to comment.