InferAddressSpaces: Fix bug about replacing addrspacecast

InferAddressSpaces assumes the pointee type of addrspacecast
is the same as the operand, which is not always true and causes
invalid IR.

This bug cause build failure in HCC.

This patch fixes that.

Differential Revision: https://reviews.llvm.org/D39432

llvm-svn: 316957
This commit is contained in:
Yaxun Liu 2017-10-30 21:19:41 +00:00
parent 5a166048f0
commit d23f23d81c
2 changed files with 18 additions and 0 deletions

View File

@ -971,6 +971,11 @@ bool InferAddressSpaces::rewriteWithNewAddressSpaces(
if (AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(CurUser)) {
unsigned NewAS = NewV->getType()->getPointerAddressSpace();
if (ASC->getDestAddressSpace() == NewAS) {
if (ASC->getType()->getPointerElementType() !=
NewV->getType()->getPointerElementType()) {
NewV = CastInst::Create(Instruction::BitCast, NewV,
ASC->getType(), "", ASC);
}
ASC->replaceAllUsesWith(NewV);
DeadInstructions.push_back(ASC);
continue;

View File

@ -15,6 +15,19 @@ define void @addrspacecast_gep_addrspacecast(i32 addrspace(3)* %ptr) {
ret void
}
; CHECK-LABEL: @addrspacecast_different_pointee_type(
; CHECK: [[GEP:%.*]] = getelementptr i32, i32 addrspace(3)* %ptr, i64 9
; CHECK: [[CAST:%.*]] = bitcast i32 addrspace(3)* [[GEP]] to i8 addrspace(3)*
; CHECK-NEXT: store i8 8, i8 addrspace(3)* [[CAST]], align 8
; CHECK-NEXT: ret void
define void @addrspacecast_different_pointee_type(i32 addrspace(3)* %ptr) {
%asc0 = addrspacecast i32 addrspace(3)* %ptr to i32 addrspace(4)*
%gep0 = getelementptr i32, i32 addrspace(4)* %asc0, i64 9
%asc1 = addrspacecast i32 addrspace(4)* %gep0 to i8 addrspace(3)*
store i8 8, i8 addrspace(3)* %asc1, align 8
ret void
}
; CHECK-LABEL: @addrspacecast_to_memory(
; CHECK: %gep0 = getelementptr i32, i32 addrspace(3)* %ptr, i64 9
; CHECK-NEXT: store volatile i32 addrspace(3)* %gep0, i32 addrspace(3)* addrspace(1)* undef