mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
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
This commit is contained in:
parent
159d252dca
commit
38ade2ebbf
@ -2243,6 +2243,12 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
|
||||
Type *DstElTy = DstPTy->getElementType();
|
||||
Type *SrcElTy = SrcPTy->getElementType();
|
||||
|
||||
// Casting pointers between the same type, but with different address spaces
|
||||
// is an addrspace cast rather than a bitcast.
|
||||
if ((DstElTy == SrcElTy) &&
|
||||
(DstPTy->getAddressSpace() != SrcPTy->getAddressSpace()))
|
||||
return new AddrSpaceCastInst(Src, DestTy);
|
||||
|
||||
// If we are casting a alloca to a pointer to a type of the same
|
||||
// size, rewrite the allocation instruction to allocate the "right" type.
|
||||
// There is no need to modify malloc calls because it is their bitcast that
|
||||
|
@ -65,3 +65,22 @@ define { i8, i8 } @inbounds_after_addrspacecast() {
|
||||
ret { i8, i8 } %insert
|
||||
}
|
||||
|
||||
|
||||
declare spir_func <16 x i32> @my_extern_func()
|
||||
|
||||
; check that a bitcast is not generated when we need an addrspace cast
|
||||
define void @bitcast_after_gep(<16 x i32>* %t0) {
|
||||
; CHECK-LABEL: @bitcast_after_gep(
|
||||
; CHECK-NEXT: [[T4:%.*]] = addrspacecast <16 x i32>* [[T0:%.*]] to <16 x i32> addrspace(3)*
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call spir_func <16 x i32> @my_extern_func()
|
||||
; CHECK-NEXT: store <16 x i32> [[CALL]], <16 x i32> addrspace(3)* [[T4]], align 64
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%t1 = bitcast <16 x i32>* %t0 to [16 x i32]*
|
||||
%t2 = addrspacecast [16 x i32]* %t1 to [16 x i32] addrspace(3)*
|
||||
%t3 = getelementptr inbounds [16 x i32], [16 x i32] addrspace(3)* %t2, i64 0, i64 0
|
||||
%t4 = bitcast i32 addrspace(3)* %t3 to <16 x i32> addrspace(3)*
|
||||
%call = call spir_func <16 x i32> @my_extern_func()
|
||||
store <16 x i32> %call, <16 x i32> addrspace(3)* %t4
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user