llvm.org GIT mirror llvm / 79e3fb5
Bug 18228 - Fix accepting bitcasts between vectors of pointers with a different number of elements. Bitcasts were passing with vectors of pointers with different number of elements since the number of elements was checking SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements() which isn't helpful. The addrspacecast was also wrong, but that case at least is caught by the verifier. Refactor bitcast and addrspacecast handling in castIsValid to be more readable and fix this problem. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199821 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 6 years ago
3 changed file(s) with 64 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
28172817 return false;
28182818 return SrcTy->getScalarType()->isIntegerTy() &&
28192819 DstTy->getScalarType()->isPointerTy();
2820 case Instruction::BitCast:
2820 case Instruction::BitCast: {
2821 PointerType *SrcPtrTy = dyn_cast(SrcTy->getScalarType());
2822 PointerType *DstPtrTy = dyn_cast(DstTy->getScalarType());
2823
28212824 // BitCast implies a no-op cast of type only. No bits change.
28222825 // However, you can't cast pointers to anything but pointers.
2823 if (SrcTy->isPtrOrPtrVectorTy() != DstTy->isPtrOrPtrVectorTy())
2826 if (!SrcPtrTy != !DstPtrTy)
28242827 return false;
28252828
28262829 // For non-pointer cases, the cast is okay if the source and destination bit
28272830 // widths are identical.
2828 if (!SrcTy->isPtrOrPtrVectorTy())
2831 if (!SrcPtrTy)
28292832 return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
28302833
2831 // If both are pointers then the address spaces must match and vector of
2832 // pointers must have the same number of elements.
2833 return SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace() &&
2834 SrcTy->isVectorTy() == DstTy->isVectorTy() &&
2835 (!SrcTy->isVectorTy() ||
2836 SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements());
2837
2838 case Instruction::AddrSpaceCast:
2839 return SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
2840 SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace() &&
2841 SrcTy->isVectorTy() == DstTy->isVectorTy() &&
2842 (!SrcTy->isVectorTy() ||
2843 SrcTy->getVectorNumElements() == SrcTy->getVectorNumElements());
2834 // If both are pointers then the address spaces must match.
2835 if (SrcPtrTy->getAddressSpace() != DstPtrTy->getAddressSpace())
2836 return false;
2837
2838 // A vector of pointers must have the same number of elements.
2839 if (VectorType *SrcVecTy = dyn_cast(SrcTy)) {
2840 if (VectorType *DstVecTy = dyn_cast(DstTy))
2841 return (SrcVecTy->getNumElements() == DstVecTy->getNumElements());
2842
2843 return false;
2844 }
2845
2846 return true;
2847 }
2848 case Instruction::AddrSpaceCast: {
2849 PointerType *SrcPtrTy = dyn_cast(SrcTy->getScalarType());
2850 if (!SrcPtrTy)
2851 return false;
2852
2853 PointerType *DstPtrTy = dyn_cast(DstTy->getScalarType());
2854 if (!DstPtrTy)
2855 return false;
2856
2857 if (SrcPtrTy->getAddressSpace() == DstPtrTy->getAddressSpace())
2858 return false;
2859
2860 if (VectorType *SrcVecTy = dyn_cast(SrcTy)) {
2861 if (VectorType *DstVecTy = dyn_cast(DstTy))
2862 return (SrcVecTy->getNumElements() == DstVecTy->getNumElements());
2863
2864 return false;
2865 }
2866
2867 return true;
2868 }
28442869 }
28452870 }
28462871
0 ; RUN: not llvm-as < %s 2>&1 | FileCheck %s
1
2 ; CHECK: invalid cast opcode for cast from '<4 x i32*>' to '<2 x i32*>'
3 define <2 x i32*> @illegal_vector_pointer_bitcast_num_elements(<4 x i32*> %c) {
4 %bc = bitcast <4 x i32*> %c to <2 x i32*>
5 ret <2 x i32*> %bc
6 }
144144
145145 Type *V2Int64PtrTy = VectorType::get(Int64PtrTy, 2);
146146 Type *V2Int32PtrTy = VectorType::get(Int32PtrTy, 2);
147 Type *V4Int32PtrTy = VectorType::get(Int32PtrTy, 4);
147148
148149 const Constant* c8 = Constant::getNullValue(V8x8Ty);
149150 const Constant* c64 = Constant::getNullValue(V8x64Ty);
202203 EXPECT_TRUE(CastInst::isBitCastable(V2Int32PtrTy, V2Int64PtrTy));
203204 EXPECT_FALSE(CastInst::isBitCastable(V2Int32Ty, V2Int64Ty));
204205 EXPECT_FALSE(CastInst::isBitCastable(V2Int64Ty, V2Int32Ty));
206
207
208 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,
209 Constant::getNullValue(V4Int32PtrTy),
210 V2Int32PtrTy));
211 EXPECT_FALSE(CastInst::castIsValid(Instruction::BitCast,
212 Constant::getNullValue(V2Int32PtrTy),
213 V4Int32PtrTy));
214
215 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,
216 Constant::getNullValue(V4Int32PtrAS1Ty),
217 V2Int32PtrTy));
218 EXPECT_FALSE(CastInst::castIsValid(Instruction::AddrSpaceCast,
219 Constant::getNullValue(V2Int32PtrTy),
220 V4Int32PtrAS1Ty));
205221
206222
207223 // Check that assertion is not hit when creating a cast with a vector of