}
if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0))) {
- if (I->hasOneUse()) {
- // Push extractelement into predecessor operation if legal and
- // profitable to do so
- if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
- bool isConstantElt = isa<ConstantInt>(EI.getOperand(1));
- if (CheapToScalarize(BO, isConstantElt)) {
- Value *newEI0 =
- Builder->CreateExtractElement(BO->getOperand(0), EI.getOperand(1),
- EI.getName()+".lhs");
- Value *newEI1 =
- Builder->CreateExtractElement(BO->getOperand(1), EI.getOperand(1),
- EI.getName()+".rhs");
- return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1);
- }
- } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
- // 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)) {
+ // Push extractelement into predecessor operation if legal and
+ // profitable to do so
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
+ if (I->hasOneUse() &&
+ CheapToScalarize(BO, isa<ConstantInt>(EI.getOperand(1)))) {
+ Value *newEI0 =
+ Builder->CreateExtractElement(BO->getOperand(0), EI.getOperand(1),
+ EI.getName()+".lhs");
+ Value *newEI1 =
+ Builder->CreateExtractElement(BO->getOperand(1), EI.getOperand(1),
+ EI.getName()+".rhs");
+ return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1);
+ }
+ } else if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) {
// Extracting the inserted element?
if (IE->getOperand(2) == EI.getOperand(1))
return ReplaceInstUsesWith(EI, IE->getOperand(1));
+++ /dev/null
-; RUN: opt %s -instcombine | llvm-dis | FileCheck %s
-
-; The load replacing the extract element must occur before the call
-; that may modify local array a.
-
-declare void @mod_a_func(<4 x float>* %a);
-
-; CHECK: load float* %arraydecay1, align 16
-; CHECK: call void @mod_a_func
-
-define void @cl_jpegenc_k2(<4 x float> addrspace(1)* %src, float addrspace(1)* %dst) {
- %a = alloca [2 x <4 x float>], align 16
- %arraydecay = getelementptr [2 x <4 x float>]* %a, i32 0, i32 0
- %arrayidx31 = getelementptr <4 x float> addrspace(1)* %src, i32 0
- %tmp32 = load <4 x float> addrspace(1)* %arrayidx31
- store <4 x float> %tmp32, <4 x float>* %arraydecay, align 16
- %tmp86 = load <4 x float>* %arraydecay, align 16
- call void @mod_a_func(<4 x float>* %arraydecay)
- %arrayidx132 = getelementptr float addrspace(1)* %dst, i32 0
- %tmp236 = extractelement <4 x float> %tmp86, i32 0
- store float %tmp236, float addrspace(1)* %arrayidx132
- ret void
-}
\ No newline at end of file