diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2014-05-01 22:12:39 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2014-05-01 22:12:39 +0000 |
commit | d4b4f2d3402c0e94730646eb63874fa5265602f5 (patch) | |
tree | 01cee689a4799fee847cf1c19e07e786ace465d7 /lib/Bitcode | |
parent | 6010d958a029f8887ca481c96eca66742a0810dc (diff) | |
download | llvm-d4b4f2d3402c0e94730646eb63874fa5265602f5.tar.gz llvm-d4b4f2d3402c0e94730646eb63874fa5265602f5.tar.bz2 llvm-d4b4f2d3402c0e94730646eb63874fa5265602f5.tar.xz |
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207801 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 34 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 6 |
2 files changed, 30 insertions, 10 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 74e8439141..1b2cf76f3e 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/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); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 92965fa7e4..23374872df 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1087,12 +1087,14 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_CE_EXTRACTELT; Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getTypeID(C->getOperand(1)->getType())); Record.push_back(VE.getValueID(C->getOperand(1))); break; case Instruction::InsertElement: Code = bitc::CST_CODE_CE_INSERTELT; Record.push_back(VE.getValueID(C->getOperand(0))); Record.push_back(VE.getValueID(C->getOperand(1))); + Record.push_back(VE.getTypeID(C->getOperand(2)->getType())); Record.push_back(VE.getValueID(C->getOperand(2))); break; case Instruction::ShuffleVector: @@ -1253,13 +1255,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::ExtractElement: Code = bitc::FUNC_CODE_INST_EXTRACTELT; PushValueAndType(I.getOperand(0), InstID, Vals, VE); - pushValue(I.getOperand(1), InstID, Vals, VE); + PushValueAndType(I.getOperand(1), InstID, Vals, VE); break; case Instruction::InsertElement: Code = bitc::FUNC_CODE_INST_INSERTELT; PushValueAndType(I.getOperand(0), InstID, Vals, VE); pushValue(I.getOperand(1), InstID, Vals, VE); - pushValue(I.getOperand(2), InstID, Vals, VE); + PushValueAndType(I.getOperand(2), InstID, Vals, VE); break; case Instruction::ShuffleVector: Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; |