Skip to content

Commit d83beb8

Browse files
committed
Fix InstCombine address space assert
Workaround bug where the InstCombine pass was asserting on the IR added in lit test, where we have a bitcast instruction after a GEP from an addrspace cast. The second bitcast in the test was getting combined into `bitcast <16 x i32>* %0 to <16 x i32> addrspace(3)*`, which looks like it should be an addrspace cast instruction instead. Otherwise if control flow is allowed to continue as it is now we create a GEP instruction `<badref> = getelementptr inbounds <16 x i32>, <16 x i32>* %0, i32 0`. However because the type of this instruction doesn't match the address space we hit an assert when replacing the bitcast with that GEP. ``` void llvm::Value::doRAUW(llvm::Value*, bool): Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!"' failed. ``` Differential Revision: https://reviews.llvm.org/D50058 llvm-svn: 338395
1 parent bdcf6ad commit d83beb8

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,12 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
22432243
Type *DstElTy = DstPTy->getElementType();
22442244
Type *SrcElTy = SrcPTy->getElementType();
22452245

2246+
// Casting pointers between the same type, but with different address spaces
2247+
// is an addrspace cast rather than a bitcast.
2248+
if ((DstElTy == SrcElTy) &&
2249+
(DstPTy->getAddressSpace() != SrcPTy->getAddressSpace()))
2250+
return new AddrSpaceCastInst(Src, DestTy);
2251+
22462252
// If we are casting a alloca to a pointer to a type of the same
22472253
// size, rewrite the allocation instruction to allocate the "right" type.
22482254
// There is no need to modify malloc calls because it is their bitcast that

llvm/test/Transforms/InstCombine/gep-addrspace.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,22 @@ define { i8, i8 } @inbounds_after_addrspacecast() {
6565
ret { i8, i8 } %insert
6666
}
6767

68+
69+
declare spir_func <16 x i32> @my_extern_func()
70+
71+
; check that a bitcast is not generated when we need an addrspace cast
72+
define void @bitcast_after_gep(<16 x i32>* %t0) {
73+
; CHECK-LABEL: @bitcast_after_gep(
74+
; CHECK-NEXT: [[T4:%.*]] = addrspacecast <16 x i32>* [[T0:%.*]] to <16 x i32> addrspace(3)*
75+
; CHECK-NEXT: [[CALL:%.*]] = call spir_func <16 x i32> @my_extern_func()
76+
; CHECK-NEXT: store <16 x i32> [[CALL]], <16 x i32> addrspace(3)* [[T4]], align 64
77+
; CHECK-NEXT: ret void
78+
;
79+
%t1 = bitcast <16 x i32>* %t0 to [16 x i32]*
80+
%t2 = addrspacecast [16 x i32]* %t1 to [16 x i32] addrspace(3)*
81+
%t3 = getelementptr inbounds [16 x i32], [16 x i32] addrspace(3)* %t2, i64 0, i64 0
82+
%t4 = bitcast i32 addrspace(3)* %t3 to <16 x i32> addrspace(3)*
83+
%call = call spir_func <16 x i32> @my_extern_func()
84+
store <16 x i32> %call, <16 x i32> addrspace(3)* %t4
85+
ret void
86+
}

0 commit comments

Comments
 (0)