Skip to content

Commit 4034b9f

Browse files
committedAug 2, 2015
Fix invalid shufflevector operands
This patch fixes bug 23800 ( https://llvm.org/bugs/show_bug.cgi?id=23800#c2 ). There existed a case where the index operand from extractelement was directly used to create a shufflevector mask. Since the index can be of any integral type but the mask must only contain 32 bit integers a 64 bit index operand led to an assertion error later on. Committed on behalf of mpflanzer (Moritz Pflanzer) Differential Revision: http://reviews.llvm.org/D10838 llvm-svn: 243851
1 parent 87368fd commit 4034b9f

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed
 

‎clang/lib/CodeGen/CGExprScalar.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,16 @@ static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx,
11621162
return llvm::ConstantInt::get(I32Ty, Off+MV);
11631163
}
11641164

1165+
static llvm::Constant *getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty) {
1166+
if (C->getBitWidth() != 32) {
1167+
assert(llvm::ConstantInt::isValueValidForType(I32Ty,
1168+
C->getZExtValue()) &&
1169+
"Index operand too large for shufflevector mask!");
1170+
return llvm::ConstantInt::get(I32Ty, C->getZExtValue());
1171+
}
1172+
return C;
1173+
}
1174+
11651175
Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
11661176
bool Ignore = TestAndClearIgnoreResultAssign();
11671177
(void)Ignore;
@@ -1212,7 +1222,8 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
12121222
Value *LHS = nullptr, *RHS = nullptr;
12131223
if (CurIdx == 0) {
12141224
// insert into undef -> shuffle (src, undef)
1215-
Args.push_back(C);
1225+
// shufflemask must use an i32
1226+
Args.push_back(getAsInt32(C, CGF.Int32Ty));
12161227
Args.resize(ResElts, llvm::UndefValue::get(CGF.Int32Ty));
12171228

12181229
LHS = EI->getVectorOperand();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -emit-llvm -O0 %s -o - | FileCheck %s
2+
3+
// The shuffle vector mask must always be of i32 vector type
4+
// See http://reviews.llvm.org/D10838 and https://llvm.org/bugs/show_bug.cgi?id=23800#c2
5+
// for more information about a bug where a 64 bit index operand causes the generation
6+
// of an invalid mask
7+
8+
typedef unsigned int uint2 __attribute((ext_vector_type(2)));
9+
10+
void vector_shufflevector_valid(void) {
11+
//CHECK: {{%.*}} = shufflevector <2 x i32> {{%.*}}, <2 x i32> undef, <2 x i32> <i32 0, i32 undef>
12+
(uint2)(((uint2)(0)).s0, 0);
13+
}

0 commit comments

Comments
 (0)
Please sign in to comment.