[X86] Update handling in CGBuiltin to be tolerant of out of range immediates.
D48464 contains changes that will loosen some of the range checks in SemaChecking to a DefaultError warning that can be disabled.
This patch adds explicit masking to avoid using the upper bits of immediates to gracefully handle the warning being disabled.
llvm-svn: 335308
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 739f234..b9430e6 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -9031,10 +9031,14 @@
case X86::BI__builtin_ia32_vec_ext_v32qi:
case X86::BI__builtin_ia32_vec_ext_v16hi:
case X86::BI__builtin_ia32_vec_ext_v8si:
- case X86::BI__builtin_ia32_vec_ext_v4di:
+ case X86::BI__builtin_ia32_vec_ext_v4di: {
+ unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
+ uint64_t Index = cast<ConstantInt>(Ops[1])->getZExtValue();
+ Index &= NumElts - 1;
// These builtins exist so we can ensure the index is an ICE and in range.
// Otherwise we could just do this in the header file.
- return Builder.CreateExtractElement(Ops[0], Ops[1]);
+ return Builder.CreateExtractElement(Ops[0], Index);
+ }
case X86::BI__builtin_ia32_vec_set_v16qi:
case X86::BI__builtin_ia32_vec_set_v8hi:
case X86::BI__builtin_ia32_vec_set_v4si:
@@ -9042,10 +9046,14 @@
case X86::BI__builtin_ia32_vec_set_v32qi:
case X86::BI__builtin_ia32_vec_set_v16hi:
case X86::BI__builtin_ia32_vec_set_v8si:
- case X86::BI__builtin_ia32_vec_set_v4di:
+ case X86::BI__builtin_ia32_vec_set_v4di: {
+ unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
+ unsigned Index = cast<ConstantInt>(Ops[2])->getZExtValue();
+ Index &= NumElts - 1;
// These builtins exist so we can ensure the index is an ICE and in range.
// Otherwise we could just do this in the header file.
- return Builder.CreateInsertElement(Ops[0], Ops[1], Ops[2]);
+ return Builder.CreateInsertElement(Ops[0], Ops[1], Index);
+ }
case X86::BI_mm_setcsr:
case X86::BI__builtin_ia32_ldmxcsr: {
Address Tmp = CreateMemTemp(E->getArg(0)->getType());
@@ -9311,8 +9319,7 @@
// extract (0, 1)
unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
- llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
- Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
+ Ops[1] = Builder.CreateExtractElement(Ops[1], Index, "extract");
// cast pointer to i64 & store
Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
@@ -9336,7 +9343,12 @@
case X86::BI__builtin_ia32_extracti64x2_512_mask: {
llvm::Type *DstTy = ConvertType(E->getType());
unsigned NumElts = DstTy->getVectorNumElements();
- unsigned Index = cast<ConstantInt>(Ops[1])->getZExtValue() * NumElts;
+ unsigned SrcNumElts = Ops[0]->getType()->getVectorNumElements();
+ unsigned SubVectors = SrcNumElts / NumElts;
+ unsigned Index = cast<ConstantInt>(Ops[1])->getZExtValue();
+ assert(llvm::isPowerOf2_32(SubVectors) && "Expected power of 2 subvectors");
+ Index &= SubVectors - 1; // Remove any extra bits.
+ Index *= NumElts;
uint32_t Indices[16];
for (unsigned i = 0; i != NumElts; ++i)
@@ -9370,7 +9382,11 @@
case X86::BI__builtin_ia32_inserti64x2_512: {
unsigned DstNumElts = Ops[0]->getType()->getVectorNumElements();
unsigned SrcNumElts = Ops[1]->getType()->getVectorNumElements();
- unsigned Index = cast<ConstantInt>(Ops[2])->getZExtValue() * SrcNumElts;
+ unsigned SubVectors = DstNumElts / SrcNumElts;
+ unsigned Index = cast<ConstantInt>(Ops[2])->getZExtValue();
+ assert(llvm::isPowerOf2_32(SubVectors) && "Expected power of 2 subvectors");
+ Index &= SubVectors - 1; // Remove any extra bits.
+ Index *= SrcNumElts;
uint32_t Indices[16];
for (unsigned i = 0; i != DstNumElts; ++i)
@@ -9571,7 +9587,7 @@
case X86::BI__builtin_ia32_palignr128:
case X86::BI__builtin_ia32_palignr256:
case X86::BI__builtin_ia32_palignr512: {
- unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
+ unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0xff;
unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
assert(NumElts % 16 == 0);
@@ -9611,7 +9627,7 @@
case X86::BI__builtin_ia32_alignq256:
case X86::BI__builtin_ia32_alignq512: {
unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
- unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
+ unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0xff;
// Mask the shift amount to width of two vectors.
ShiftVal &= (2 * NumElts) - 1;
@@ -9696,7 +9712,7 @@
case X86::BI__builtin_ia32_pslldqi128_byteshift:
case X86::BI__builtin_ia32_pslldqi256_byteshift:
case X86::BI__builtin_ia32_pslldqi512_byteshift: {
- unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
+ unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue() & 0xff;
llvm::Type *ResultType = Ops[0]->getType();
// Builtin type is vXi64 so multiply by 8 to get bytes.
unsigned NumElts = ResultType->getVectorNumElements() * 8;
@@ -9726,7 +9742,7 @@
case X86::BI__builtin_ia32_psrldqi128_byteshift:
case X86::BI__builtin_ia32_psrldqi256_byteshift:
case X86::BI__builtin_ia32_psrldqi512_byteshift: {
- unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
+ unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue() & 0xff;
llvm::Type *ResultType = Ops[0]->getType();
// Builtin type is vXi64 so multiply by 8 to get bytes.
unsigned NumElts = ResultType->getVectorNumElements() * 8;
@@ -10170,7 +10186,7 @@
case X86::BI__builtin_ia32_cmpps256:
case X86::BI__builtin_ia32_cmppd:
case X86::BI__builtin_ia32_cmppd256: {
- unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
+ unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x1f;
// If this one of the SSE immediates, we can use native IR.
if (CC < 8) {
FCmpInst::Predicate Pred;