From d23f23d81cbb6730e745a996148adea237a77f84 Mon Sep 17 00:00:00 2001 From: Yaxun Liu Date: Mon, 30 Oct 2017 21:19:41 +0000 Subject: [PATCH] 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 --- llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp | 5 +++++ .../AMDGPU/infer-addrspacecast.ll | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp b/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp index fba80abf650c..7d66c0f73821 100644 --- a/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp +++ b/llvm/lib/Transforms/Scalar/InferAddressSpaces.cpp @@ -971,6 +971,11 @@ bool InferAddressSpaces::rewriteWithNewAddressSpaces( if (AddrSpaceCastInst *ASC = dyn_cast(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; diff --git a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/infer-addrspacecast.ll b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/infer-addrspacecast.ll index 73829e86527c..74a2595252d7 100644 --- a/llvm/test/Transforms/InferAddressSpaces/AMDGPU/infer-addrspacecast.ll +++ b/llvm/test/Transforms/InferAddressSpaces/AMDGPU/infer-addrspacecast.ll @@ -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