aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-09-08 03:44:51 +0000
committerChris Lattner <sabre@nondot.org>2009-09-08 03:44:51 +0000
commit4cb81bdd5689a5bbe8c270c70f503c9d9779d5b1 (patch)
treec9a93107a31ba0c8408d09bab38ebfc3efe17ab5 /lib/Transforms
parentc8dee3f7ad60e76bdac597ee47f8d9e3470cc8ff (diff)
downloadexternal_llvm-4cb81bdd5689a5bbe8c270c70f503c9d9779d5b1.zip
external_llvm-4cb81bdd5689a5bbe8c270c70f503c9d9779d5b1.tar.gz
external_llvm-4cb81bdd5689a5bbe8c270c70f503c9d9779d5b1.tar.bz2
instcombine transforms vector loads that are only used by
extractelement operations into a bitcast of the pointer, then a gep, then a scalar load. Disable this when the vector only has one element, because it leads to infinite loops in instcombine (PR4908). This transformation seems like a really bad idea to me, as it will likely disable CSE of vector load/stores etc and can be better done in the code generator when profitable. This goes all the way back to the first days of packed types, r25299 specifically. I'll let those people who care about the performance of vector code decide what to do with this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81185 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp49
1 files changed, 27 insertions, 22 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 962a545..17d7555 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -12080,7 +12080,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
// that element. When the elements are not identical, we cannot replace yet
// (we do that below, but only when the index is constant).
Constant *op0 = C->getOperand(0);
- for (unsigned i = 1; i < C->getNumOperands(); ++i)
+ for (unsigned i = 1; i != C->getNumOperands(); ++i)
if (C->getOperand(i) != op0) {
op0 = 0;
break;
@@ -12093,8 +12093,7 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
// find a previously computed scalar that was inserted into the vector.
if (ConstantInt *IdxC = dyn_cast<ConstantInt>(EI.getOperand(1))) {
unsigned IndexVal = IdxC->getZExtValue();
- unsigned VectorWidth =
- cast<VectorType>(EI.getOperand(0)->getType())->getNumElements();
+ unsigned VectorWidth = EI.getVectorOperandType()->getNumElements();
// If this is extracting an invalid index, turn this into undef, to avoid
// crashing the code below.
@@ -12146,25 +12145,31 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1);
}
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
- unsigned AS = LI->getPointerAddressSpace();
- Value *Ptr = Builder->CreateBitCast(I->getOperand(0),
- PointerType::get(EI.getType(), AS),
- I->getOperand(0)->getName());
- Value *GEP =
- Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1),
- I->getName()+".gep");
-
- LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
-
- // Make sure the Load goes before the load instruction in the source,
- // not wherever the extract happens to be.
- if (Instruction *P = dyn_cast<Instruction>(Ptr))
- P->moveBefore(I);
- if (Instruction *G = dyn_cast<Instruction>(GEP))
- G->moveBefore(I);
- Load->moveBefore(I);
-
- return ReplaceInstUsesWith(EI, Load);
+// r25299
+ // Instead of loading a vector, then doing an extract element out of it,
+ // just bitcast the pointer operand, do a gep, then load the result.
+ // This shrinks the vector load to a scalar load.
+ if (EI.getVectorOperandType()->getNumElements() != 1) {
+ unsigned AS = LI->getPointerAddressSpace();
+ Value *Ptr = Builder->CreateBitCast(I->getOperand(0),
+ PointerType::get(EI.getType(), AS),
+ I->getOperand(0)->getName());
+ Value *GEP =
+ Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1),
+ I->getName()+".gep");
+
+ LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
+
+ // Make sure the Load goes before the load instruction in the source,
+ // not wherever the extract happens to be.
+ if (Instruction *P = dyn_cast<Instruction>(Ptr))
+ P->moveBefore(I);
+ if (Instruction *G = dyn_cast<Instruction>(GEP))
+ G->moveBefore(I);
+ Load->moveBefore(I);
+
+ return ReplaceInstUsesWith(EI, Load);
+ }
}
}
if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) {