Skip to content

Commit 24a4901

Browse files
author
git apple-llvm automerger
committed
Merge commit '4a3e0001e367' from llvm.org/main into next
2 parents e441298 + 4a3e000 commit 24a4901

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

llvm/lib/IR/Instructions.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2965,19 +2965,23 @@ unsigned CastInst::isEliminableCastPair(Instruction::CastOps firstOp,
29652965
// zext, sext -> zext, because sext can't sign extend after zext
29662966
return Instruction::ZExt;
29672967
case 11: {
2968-
// inttoptr, ptrtoint/ptrtoaddr -> bitcast if SrcSize<=PtrSize/AddrSize
2969-
// and SrcSize==DstSize
2968+
// inttoptr, ptrtoint/ptrtoaddr -> integer cast
29702969
if (!DL)
29712970
return 0;
29722971
unsigned MidSize = secondOp == Instruction::PtrToAddr
29732972
? DL->getAddressSizeInBits(MidTy)
29742973
: DL->getPointerTypeSizeInBits(MidTy);
29752974
unsigned SrcSize = SrcTy->getScalarSizeInBits();
29762975
unsigned DstSize = DstTy->getScalarSizeInBits();
2977-
// TODO: Could also produce zext or trunc here.
2978-
if (SrcSize <= MidSize && SrcSize == DstSize)
2979-
return Instruction::BitCast;
2980-
return 0;
2976+
// If the middle size is smaller than both source and destination,
2977+
// an additional masking operation would be required.
2978+
if (MidSize < SrcSize && MidSize < DstSize)
2979+
return 0;
2980+
if (DstSize < SrcSize)
2981+
return Instruction::Trunc;
2982+
if (DstSize > SrcSize)
2983+
return Instruction::ZExt;
2984+
return Instruction::BitCast;
29812985
}
29822986
case 12:
29832987
// addrspacecast, addrspacecast -> bitcast, if SrcAS == DstAS

llvm/test/Transforms/InstCombine/ptrtoaddr.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ define i64 @ptrtoaddr_inttoptr_arg(i64 %a) {
2323
define i32 @ptrtoaddr_inttoptr_arg_addrsize(i32 %a) {
2424
; CHECK-LABEL: define i32 @ptrtoaddr_inttoptr_arg_addrsize(
2525
; CHECK-SAME: i32 [[A:%.*]]) {
26-
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[A]] to i64
27-
; CHECK-NEXT: [[TOPTR:%.*]] = inttoptr i64 [[TMP1]] to ptr addrspace(1)
28-
; CHECK-NEXT: [[TOADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[TOPTR]] to i32
29-
; CHECK-NEXT: ret i32 [[TOADDR]]
26+
; CHECK-NEXT: ret i32 [[A]]
3027
;
3128
%toptr = inttoptr i32 %a to ptr addrspace(1)
3229
%toaddr = ptrtoaddr ptr addrspace(1) %toptr to i32

llvm/unittests/IR/InstructionsTest.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,12 +606,14 @@ TEST(InstructionTest, ConstrainedTrans) {
606606

607607
TEST(InstructionsTest, isEliminableCastPair) {
608608
LLVMContext C;
609-
DataLayout DL1("p1:32:32");
609+
DataLayout DL1("p1:32:32-p2:64:64:64:32");
610610

611611
Type *Int16Ty = Type::getInt16Ty(C);
612+
Type *Int32Ty = Type::getInt32Ty(C);
612613
Type *Int64Ty = Type::getInt64Ty(C);
613614
Type *PtrTy64 = PointerType::get(C, 0);
614615
Type *PtrTy32 = PointerType::get(C, 1);
616+
Type *PtrTy64_32 = PointerType::get(C, 2);
615617

616618
// Source and destination pointers have same size -> bitcast.
617619
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::PtrToInt,
@@ -637,6 +639,42 @@ TEST(InstructionsTest, isEliminableCastPair) {
637639
Int64Ty, &DL1),
638640
0U);
639641

642+
// Destination larger than source. Pointer type same as destination.
643+
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
644+
CastInst::PtrToInt, Int16Ty, PtrTy64,
645+
Int64Ty, &DL1),
646+
CastInst::ZExt);
647+
648+
// Destination larger than source. Pointer type different from destination.
649+
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
650+
CastInst::PtrToInt, Int16Ty, PtrTy32,
651+
Int64Ty, &DL1),
652+
CastInst::ZExt);
653+
654+
// Destination smaller than source. Pointer type same as source.
655+
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
656+
CastInst::PtrToInt, Int64Ty, PtrTy64,
657+
Int16Ty, &DL1),
658+
CastInst::Trunc);
659+
660+
// Destination smaller than source. Pointer type different from source.
661+
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
662+
CastInst::PtrToInt, Int64Ty, PtrTy32,
663+
Int16Ty, &DL1),
664+
CastInst::Trunc);
665+
666+
// ptrtoaddr with address size != pointer size. Truncating case.
667+
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
668+
CastInst::PtrToAddr, Int64Ty,
669+
PtrTy64_32, Int32Ty, &DL1),
670+
CastInst::Trunc);
671+
672+
// ptrtoaddr with address size != pointer size. Non-truncating case.
673+
EXPECT_EQ(CastInst::isEliminableCastPair(CastInst::IntToPtr,
674+
CastInst::PtrToAddr, Int32Ty,
675+
PtrTy64_32, Int32Ty, &DL1),
676+
CastInst::BitCast);
677+
640678
// Test that we don't eliminate bitcasts between different address spaces,
641679
// or if we don't have available pointer size information.
642680
DataLayout DL2("e-p:32:32:32-p1:16:16:16-p2:64:64:64-i1:8:8-i8:8:8-i16:16:16"

0 commit comments

Comments
 (0)