Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -3226,8 +3226,22 @@ return true; } -bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, - const DataLayout &DL) { +/// Return true if conversion is valid with an inttoptr/ptrtoint. Note that +/// the results are expected to match CastInst::isNoopCast, but we can't use +/// that directly since it doesn't check preconditions. +static bool isNoopPointerCastable(Type *SrcTy, Type *DestTy, + const DataLayout &DL) { + + if (VectorType *SrcVecTy = dyn_cast(SrcTy)) { + if (VectorType *DestVecTy = dyn_cast(DestTy)) { + if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) { + // An element by element cast. Valid if casting the elements is valid. + SrcTy = SrcVecTy->getElementType(); + DestTy = DestVecTy->getElementType(); + } + } + } + // ptrtoint and inttoptr are not allowed on non-integral pointers if (auto *PtrTy = dyn_cast(SrcTy)) if (auto *IntTy = dyn_cast(DestTy)) @@ -3238,6 +3252,14 @@ return (IntTy->getBitWidth() == DL.getPointerTypeSizeInBits(PtrTy) && !DL.isNonIntegralPointerType(PtrTy)); + return false; +} + +bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, + const DataLayout &DL) { + + if (isNoopPointerCastable(SrcTy, DestTy, DL)) + return true; return isBitCastable(SrcTy, DestTy); } Index: llvm/test/Transforms/InstCombine/call.ll =================================================================== --- llvm/test/Transforms/InstCombine/call.ll +++ llvm/test/Transforms/InstCombine/call.ll @@ -235,7 +235,7 @@ define void @test13(<2 x i32*> %A) { ; CHECK-LABEL: @test13( -; CHECK: call void bitcast +; CHECK: call void @test13a call void bitcast (void (<2 x i64>)* @test13a to void (<2 x i32*>)*)(<2 x i32*> %A) ret void } @@ -246,7 +246,7 @@ define void @test14(<2 x i64> %A) { ; CHECK-LABEL: @test14( -; CHECK: call void bitcast +; CHECK: call void @test14a call void bitcast (void (<2 x i8*>)* @test14a to void (<2 x i64>)*)(<2 x i64> %A) ret void } Index: llvm/test/Transforms/InstCombine/load.ll =================================================================== --- llvm/test/Transforms/InstCombine/load.ll +++ llvm/test/Transforms/InstCombine/load.ll @@ -385,10 +385,9 @@ define <2 x i64> @test23(<2 x i64>* %P) { ; CHECK-LABEL: @test23( -; CHECK-NEXT: [[P_PTR:%.*]] = bitcast <2 x i64>* [[P:%.*]] to <2 x i8*>* -; CHECK-NEXT: [[X:%.*]] = load <2 x i64>, <2 x i64>* [[P]], align 16 -; CHECK-NEXT: [[Y:%.*]] = load <2 x i8*>, <2 x i8*>* [[P_PTR]], align 16 -; CHECK-NEXT: call void @use.v2.p0(<2 x i8*> [[Y]]) +; CHECK-NEXT: [[X:%.*]] = load <2 x i64>, <2 x i64>* [[P:%.*]], align 16 +; CHECK-NEXT: [[Y_CAST:%.*]] = inttoptr <2 x i64> [[X]] to <2 x i8*> +; CHECK-NEXT: call void @use.v2.p0(<2 x i8*> [[Y_CAST]]) ; CHECK-NEXT: ret <2 x i64> [[X]] ; %P.ptr = bitcast <2 x i64>* %P to <2 x i8*>*