From 7c4efa6808b737b2bfc7c79872b9c16f566a7d8a Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Thu, 13 Aug 2009 05:12:13 +0000 Subject: [PATCH] When InstCombine simplifies a load -> extract element to gep -> load, place the new load by the old load instead of by the extract element because a store could have occurred between the load and extract element. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78891 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 8 ++++--- .../InstCombine/vec_extract_elt2.ll | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/InstCombine/vec_extract_elt2.ll diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index b875420e5be..04c225f7460 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -12465,12 +12465,14 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) { unsigned AS = cast(I->getOperand(0)->getType())->getAddressSpace(); Value *Ptr = InsertBitCastBefore(I->getOperand(0), - PointerType::get(EI.getType(), AS),EI); + PointerType::get(EI.getType(), AS),*I); GetElementPtrInst *GEP = GetElementPtrInst::Create(Ptr, EI.getOperand(1), I->getName()+".gep"); cast(GEP)->setIsInBounds(true); - InsertNewInstBefore(GEP, EI); - return new LoadInst(GEP); + InsertNewInstBefore(GEP, *I); + LoadInst* Load = new LoadInst(GEP, "tmp"); + InsertNewInstBefore(Load, *I); + return ReplaceInstUsesWith(EI, Load); } } if (InsertElementInst *IE = dyn_cast(I)) { diff --git a/test/Transforms/InstCombine/vec_extract_elt2.ll b/test/Transforms/InstCombine/vec_extract_elt2.ll new file mode 100644 index 00000000000..37463d23f17 --- /dev/null +++ b/test/Transforms/InstCombine/vec_extract_elt2.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | opt -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