mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
Canonicalize addrspacecast ConstExpr between different pointer types
As a follow-up to r210375 which canonicalizes addrspacecast instructions, this patch canonicalizes addrspacecast constant expressions. Given clang uses ConstantExpr::getAddrSpaceCast to emit addrspacecast cosntant expressions, this patch is also a step towards having the frontend emit canonicalized addrspacecasts. Piggyback a minor refactor in InstCombineCasts.cpp Update three affected tests in addrspacecast-alias.ll, access-non-generic.ll and constant-fold-gep.ll and added one new test in constant-fold-address-space-pointer.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211004 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f9ef37a986
commit
f6eb7e3175
@ -529,7 +529,10 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
|
||||
// Try hard to fold cast of cast because they are often eliminable.
|
||||
if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy))
|
||||
return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy);
|
||||
} else if (CE->getOpcode() == Instruction::GetElementPtr) {
|
||||
} else if (CE->getOpcode() == Instruction::GetElementPtr &&
|
||||
// Do not fold addrspacecast (gep 0, .., 0). It might make the
|
||||
// addrspacecast uncanonicalized.
|
||||
opc != Instruction::AddrSpaceCast) {
|
||||
// If all of the indexes in the GEP are null values, there is no pointer
|
||||
// adjustment going on. We might as well cast the source pointer.
|
||||
bool isAllNull = true;
|
||||
|
@ -1698,6 +1698,19 @@ Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) {
|
||||
assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) &&
|
||||
"Invalid constantexpr addrspacecast!");
|
||||
|
||||
// Canonicalize addrspacecasts between different pointer types by first
|
||||
// bitcasting the pointer type and then converting the address space.
|
||||
PointerType *SrcScalarTy = cast<PointerType>(C->getType()->getScalarType());
|
||||
PointerType *DstScalarTy = cast<PointerType>(DstTy->getScalarType());
|
||||
Type *DstElemTy = DstScalarTy->getElementType();
|
||||
if (SrcScalarTy->getElementType() != DstElemTy) {
|
||||
Type *MidTy = PointerType::get(DstElemTy, SrcScalarTy->getAddressSpace());
|
||||
if (VectorType *VT = dyn_cast<VectorType>(DstTy)) {
|
||||
// Handle vectors of pointers.
|
||||
MidTy = VectorType::get(MidTy, VT->getNumElements());
|
||||
}
|
||||
C = getBitCast(C, MidTy);
|
||||
}
|
||||
return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy);
|
||||
}
|
||||
|
||||
|
@ -1919,8 +1919,10 @@ Instruction *InstCombiner::visitAddrSpaceCast(AddrSpaceCastInst &CI) {
|
||||
Type *DestElemTy = DestTy->getElementType();
|
||||
if (SrcTy->getElementType() != DestElemTy) {
|
||||
Type *MidTy = PointerType::get(DestElemTy, SrcTy->getAddressSpace());
|
||||
if (CI.getType()->isVectorTy()) // Handle vectors of pointers.
|
||||
MidTy = VectorType::get(MidTy, CI.getType()->getVectorNumElements());
|
||||
if (VectorType *VT = dyn_cast<VectorType>(CI.getType())) {
|
||||
// Handle vectors of pointers.
|
||||
MidTy = VectorType::get(MidTy, VT->getNumElements());
|
||||
}
|
||||
|
||||
Value *NewBitCast = Builder->CreateBitCast(Src, MidTy);
|
||||
return new AddrSpaceCastInst(NewBitCast, CI.getType());
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
@i = internal addrspace(1) global i8 42
|
||||
@ia = alias internal addrspacecast (i8 addrspace(1)* @i to i8 addrspace(2)* addrspace(3)*)
|
||||
; CHECK: @ia = alias internal addrspacecast (i8 addrspace(1)* @i to i8 addrspace(2)* addrspace(3)*)
|
||||
; CHECK: @ia = alias internal addrspacecast (i8 addrspace(2)* addrspace(1)* bitcast (i8 addrspace(1)* @i to i8 addrspace(2)* addrspace(1)*) to i8 addrspace(2)* addrspace(3)*)
|
||||
|
@ -74,13 +74,13 @@ define float @ld_st_shared_f32(i32 %i, float %v) {
|
||||
ret float %sum5
|
||||
}
|
||||
|
||||
; Verifies nvptx-favor-non-generic keeps addrspacecasts between pointers of
|
||||
; different element types.
|
||||
; When hoisting an addrspacecast between different pointer types, replace the
|
||||
; addrspacecast with a bitcast.
|
||||
define i32 @ld_int_from_float() {
|
||||
; IR-LABEL: @ld_int_from_float
|
||||
; IR: addrspacecast
|
||||
; IR: load i32 addrspace(3)* bitcast (float addrspace(3)* @scalar to i32 addrspace(3)*)
|
||||
; PTX-LABEL: ld_int_from_float(
|
||||
; PTX: cvta.shared.u{{(32|64)}}
|
||||
; PTX: ld.shared.u{{(32|64)}}
|
||||
%1 = load i32* addrspacecast(float addrspace(3)* @scalar to i32*), align 4
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ define i8* @different_addrspace() nounwind noinline {
|
||||
%p = getelementptr inbounds i8* addrspacecast ([4 x i8] addrspace(12)* @p12 to i8*),
|
||||
i32 2
|
||||
ret i8* %p
|
||||
; OPT: ret i8* getelementptr (i8* addrspacecast ([4 x i8] addrspace(12)* @p12 to i8*), i32 2)
|
||||
; OPT: ret i8* getelementptr (i8* addrspacecast (i8 addrspace(12)* getelementptr inbounds ([4 x i8] addrspace(12)* @p12, i32 0, i32 0) to i8*), i32 2)
|
||||
}
|
||||
|
||||
define i8* @same_addrspace() nounwind noinline {
|
||||
|
@ -230,3 +230,13 @@ define i32 @constant_through_array_as_ptrs() {
|
||||
%b = load i32 addrspace(1)* %a, align 4
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
@shared_mem = external addrspace(3) global [0 x i8]
|
||||
|
||||
define float @canonicalize_addrspacecast(i32 %i) {
|
||||
; CHECK-LABEL: @canonicalize_addrspacecast
|
||||
; CHECK-NEXT: getelementptr inbounds float* addrspacecast (float addrspace(3)* bitcast ([0 x i8] addrspace(3)* @shared_mem to float addrspace(3)*) to float*), i32 %i
|
||||
%p = getelementptr inbounds float* addrspacecast ([0 x i8] addrspace(3)* @shared_mem to float*), i32 %i
|
||||
%v = load float* %p
|
||||
ret float %v
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user