[PATCH] Canonicalize addrspacecast between different pointer types.
Matt Arsenault
Matthew.Arsenault at amd.com
Fri Nov 15 02:24:39 PST 2013
Cast the address space with the same pointer element type
and then bitcast the type in the new address space.
addrspacecast X addrspace(M)* to Y addrspace(N)*
->
bitcast X addrspace(N)* (addrspacecast X addrspace(M)* to X addrspace(N)*) to Y addrspace(N)*
http://llvm-reviews.chandlerc.com/D2186
Files:
lib/IR/Instructions.cpp
lib/Transforms/InstCombine/InstCombineCasts.cpp
test/Transforms/InstCombine/addrspacecast.ll
Index: lib/IR/Instructions.cpp
===================================================================
--- lib/IR/Instructions.cpp
+++ lib/IR/Instructions.cpp
@@ -2282,38 +2282,25 @@
return 0;
}
case 12: {
- // addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS
// addrspacecast, addrspacecast -> addrspacecast, if SrcAS != DstAS
if (SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace())
return Instruction::AddrSpaceCast;
- return Instruction::BitCast;
+ return 0;
}
case 13:
- // FIXME: this state can be merged with (1), but the following assert
- // is useful to check the correcteness of the sequence due to semantic
- // change of bitcast.
- assert(
- SrcTy->isPtrOrPtrVectorTy() &&
- MidTy->isPtrOrPtrVectorTy() &&
- DstTy->isPtrOrPtrVectorTy() &&
- SrcTy->getPointerAddressSpace() != MidTy->getPointerAddressSpace() &&
- MidTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
- "Illegal addrspacecast, bitcast sequence!");
- // Allowed, use first cast's opcode
- return firstOp;
+ // addrspacecast, bitcast -> addrspacecast if the pointer element types
+ // are the same.
+ if (SrcTy->getPointerElementType() == DstTy->getPointerElementType())
+ return Instruction::AddrSpaceCast;
+ return 0;
+
case 14:
- // FIXME: this state can be merged with (2), but the following assert
- // is useful to check the correcteness of the sequence due to semantic
- // change of bitcast.
- assert(
- SrcTy->isPtrOrPtrVectorTy() &&
- MidTy->isPtrOrPtrVectorTy() &&
- DstTy->isPtrOrPtrVectorTy() &&
- SrcTy->getPointerAddressSpace() == MidTy->getPointerAddressSpace() &&
- MidTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() &&
- "Illegal bitcast, addrspacecast sequence!");
- // Allowed, use second cast's opcode
- return secondOp;
+ // bitcast, addrspacecast -> addrspacecast if the pointer element types
+ // are the same.
+ if (MidTy->getPointerElementType() == DstTy->getPointerElementType())
+ return Instruction::AddrSpaceCast;
+ return 0;
+
case 15:
// FIXME: this state can be merged with (1), but the following assert
// is useful to check the correcteness of the sequence due to semantic
Index: lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1853,5 +1853,22 @@
}
Instruction *InstCombiner::visitAddrSpaceCast(AddrSpaceCastInst &CI) {
- return commonCastTransforms(CI);
+ // If the destination pointer element type is not the the same as the source's
+ // do the addrspacecast to the same type, and then the bitcast in the new
+ // address space. This allows the cast to be exposed to other transforms.
+ Value *Src = CI.getOperand(0);
+ PointerType *SrcTy = cast<PointerType>(Src->getType()->getScalarType());
+ PointerType *DestTy = cast<PointerType>(CI.getType()->getScalarType());
+
+ Type *SrcElemTy = SrcTy->getElementType();
+ if (SrcElemTy != DestTy->getElementType()) {
+ Type *MidTy = PointerType::get(SrcElemTy, DestTy->getAddressSpace());
+ if (CI.getType()->isVectorTy()) // Handle vectors of pointers.
+ MidTy = VectorType::get(MidTy, CI.getType()->getVectorNumElements());
+
+ Value *NewASCast = Builder->CreateAddrSpaceCast(Src, MidTy);
+ return new BitCastInst(NewASCast, CI.getType());
+ }
+
+ return commonPointerCastTransforms(CI);
}
Index: test/Transforms/InstCombine/addrspacecast.ll
===================================================================
--- test/Transforms/InstCombine/addrspacecast.ll
+++ test/Transforms/InstCombine/addrspacecast.ll
@@ -22,10 +22,77 @@
define float* @combine_redundant_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
; CHECK-LABEL: @combine_redundant_addrspacecast_types(
-; CHECK: addrspacecast i32 addrspace(1)* %x to float*
+; CHECK-NEXT: addrspacecast i32 addrspace(1)* %x to i32*
+; CHECK-NEXT: bitcast i32* %1 to float*
; CHECK-NEXT: ret
%y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)*
%z = addrspacecast i32 addrspace(3)* %y to float*
ret float* %z
}
+define <4 x float*> @combine_redundant_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
+; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector(
+; CHECK-NEXT: addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32*>
+; CHECK-NEXT: bitcast <4 x i32*> %1 to <4 x float*>
+; CHECK-NEXT: ret
+ %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*>
+ %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x float*>
+ ret <4 x float*> %z
+}
+
+define float addrspace(2)* @combine_addrspacecast_bitcast_1(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_bitcast_1(
+; CHECK-NEXT: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK-NEXT: bitcast i32 addrspace(2)* %y to float addrspace(2)*
+; CHECK-NEXT: ret
+ %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+ %z = bitcast i32 addrspace(2)* %y to float addrspace(2)*
+ ret float addrspace(2)* %z
+}
+
+define i32 addrspace(2)* @combine_addrspacecast_bitcast_2(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_bitcast_2(
+; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK-NEXT: ret
+ %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
+ %z = bitcast float addrspace(2)* %y to i32 addrspace(2)*
+ ret i32 addrspace(2)* %z
+}
+
+define i32 addrspace(2)* @combine_bitcast_addrspacecast_1(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_bitcast_addrspacecast_1(
+; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK-NEXT: ret
+ %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
+ %z = addrspacecast i8 addrspace(1)* %y to i32 addrspace(2)*
+ ret i32 addrspace(2)* %z
+}
+
+define float addrspace(2)* @combine_bitcast_addrspacecast_2(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_bitcast_addrspacecast_2(
+; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK: bitcast i32 addrspace(2)* %1 to float addrspace(2)*
+; CHECK-NEXT: ret
+ %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)*
+ %z = addrspacecast i8 addrspace(1)* %y to float addrspace(2)*
+ ret float addrspace(2)* %z
+}
+
+define float addrspace(2)* @combine_addrspacecast_types(i32 addrspace(1)* %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_types(
+; CHECK-NEXT: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)*
+; CHECK-NEXT: bitcast i32 addrspace(2)* %1 to float addrspace(2)*
+; CHECK-NEXT: ret
+ %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)*
+ ret float addrspace(2)* %y
+}
+
+define <4 x float addrspace(2)*> @combine_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind {
+; CHECK-LABEL: @combine_addrspacecast_types_vector(
+; CHECK-NEXT: addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(2)*>
+; CHECK-NEXT: bitcast <4 x i32 addrspace(2)*> %1 to <4 x float addrspace(2)*>
+; CHECK-NEXT: ret
+ %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*>
+ ret <4 x float addrspace(2)*> %y
+}
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2186.1.patch
Type: text/x-patch
Size: 7411 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131115/666dd5ce/attachment.bin>
More information about the llvm-commits
mailing list