summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2014-05-01 22:12:39 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2014-05-01 22:12:39 +0000
commit1f10c5ea943b0f13df9d61ca22dc964760ecc45f (patch)
treebcd20bbda2b1af7b7f8a23d63c70ae6a753aad7e /llvm/lib/Bitcode/Reader
parent94cb35cb054f8fe021b1c4e89eeed15cb9697d36 (diff)
downloadbcm5719-llvm-1f10c5ea943b0f13df9d61ca22dc964760ecc45f.tar.gz
bcm5719-llvm-1f10c5ea943b0f13df9d61ca22dc964760ecc45f.zip
[IR] Make {extract,insert}element accept an index of any integer type.
Given the following C code llvm currently generates suboptimal code for x86-64: __m128 bss4( const __m128 *ptr, size_t i, size_t j ) { float f = ptr[i][j]; return (__m128) { f, f, f, f }; } ================================================= define <4 x float> @_Z4bss4PKDv4_fmm(<4 x float>* nocapture readonly %ptr, i64 %i, i64 %j) #0 { %a1 = getelementptr inbounds <4 x float>* %ptr, i64 %i %a2 = load <4 x float>* %a1, align 16, !tbaa !1 %a3 = trunc i64 %j to i32 %a4 = extractelement <4 x float> %a2, i32 %a3 %a5 = insertelement <4 x float> undef, float %a4, i32 0 %a6 = insertelement <4 x float> %a5, float %a4, i32 1 %a7 = insertelement <4 x float> %a6, float %a4, i32 2 %a8 = insertelement <4 x float> %a7, float %a4, i32 3 ret <4 x float> %a8 } ================================================= shlq $4, %rsi addq %rdi, %rsi movslq %edx, %rax vbroadcastss (%rsi,%rax,4), %xmm0 retq ================================================= The movslq is uneeded, but is present because of the trunc to i32 and then sext back to i64 that the backend adds for vbroadcastss. We can't remove it because it changes the meaning. The IR that clang generates is already suboptimal. What clang really should emit is: %a4 = extractelement <4 x float> %a2, i64 %j This patch makes that legal. A separate patch will teach clang to do it. Differential Revision: http://reviews.llvm.org/D3519 llvm-svn: 207801
Diffstat (limited to 'llvm/lib/Bitcode/Reader')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp34
1 files changed, 26 insertions, 8 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 74e8439141e..1b2cf76f3e6 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1418,7 +1418,8 @@ error_code BitcodeReader::ParseConstants() {
ValueList.getConstantFwdRef(Record[2],CurTy));
break;
}
- case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval]
+ case bitc::CST_CODE_CE_EXTRACTELT
+ : { // CE_EXTRACTELT: [opty, opval, opty, opval]
if (Record.size() < 3)
return Error(InvalidRecord);
VectorType *OpTy =
@@ -1426,20 +1427,37 @@ error_code BitcodeReader::ParseConstants() {
if (!OpTy)
return Error(InvalidRecord);
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
- Constant *Op1 = ValueList.getConstantFwdRef(Record[2],
- Type::getInt32Ty(Context));
+ Constant *Op1 = nullptr;
+ if (Record.size() == 4) {
+ Type *IdxTy = getTypeByID(Record[2]);
+ if (!IdxTy)
+ return Error(InvalidRecord);
+ Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy);
+ } else // TODO: Remove with llvm 4.0
+ Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+ if (!Op1)
+ return Error(InvalidRecord);
V = ConstantExpr::getExtractElement(Op0, Op1);
break;
}
- case bitc::CST_CODE_CE_INSERTELT: { // CE_INSERTELT: [opval, opval, opval]
+ case bitc::CST_CODE_CE_INSERTELT
+ : { // CE_INSERTELT: [opval, opval, opty, opval]
VectorType *OpTy = dyn_cast<VectorType>(CurTy);
if (Record.size() < 3 || !OpTy)
return Error(InvalidRecord);
Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
OpTy->getElementType());
- Constant *Op2 = ValueList.getConstantFwdRef(Record[2],
- Type::getInt32Ty(Context));
+ Constant *Op2 = nullptr;
+ if (Record.size() == 4) {
+ Type *IdxTy = getTypeByID(Record[2]);
+ if (!IdxTy)
+ return Error(InvalidRecord);
+ Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy);
+ } else // TODO: Remove with llvm 4.0
+ Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+ if (!Op2)
+ return Error(InvalidRecord);
V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
break;
}
@@ -2460,7 +2478,7 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Vec, *Idx;
if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
- popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx))
+ getValueTypePair(Record, OpNum, NextValueNo, Idx))
return Error(InvalidRecord);
I = ExtractElementInst::Create(Vec, Idx);
InstructionList.push_back(I);
@@ -2473,7 +2491,7 @@ error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
popValue(Record, OpNum, NextValueNo,
cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
- popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx))
+ getValueTypePair(Record, OpNum, NextValueNo, Idx))
return Error(InvalidRecord);
I = InsertElementInst::Create(Vec, Elt, Idx);
InstructionList.push_back(I);
OpenPOWER on IntegriCloud