Index: lib/Analysis/MemoryDependenceAnalysis.cpp =================================================================== --- lib/Analysis/MemoryDependenceAnalysis.cpp +++ lib/Analysis/MemoryDependenceAnalysis.cpp @@ -651,6 +651,25 @@ return MemDepResult::getDef(Inst); if (isInvariantLoad) continue; + + // To remove QueryInst in following case: + // lw a0, Addr1 <- LItoSI + // sw a0, Addr2 <- SI + // lw a0, Addr1 <- QueryInst + // + // Originally, QueryInst can't remove by GVN due to Addr1 may alias + // with Addr2. + // However, QueryInst and LItoSI load from same address, so even Addr1 + // alias to Addr2,the value load from LItoSI could propagate to QueryInst. + // MemLoc is the load address of QueryInst. + // LoadLoc is the load address of LItoSI. + if (LoadInst *LItoSI = dyn_cast(SI->getValueOperand())) { + MemoryLocation LoadLoc = MemoryLocation::get(LItoSI); + AliasResult R = AA.alias(LoadLoc, MemLoc); + if (R == MustAlias) + continue; + } + return MemDepResult::getClobber(Inst); } Index: test/Analysis/MemoryDependenceAnalysis/memdep-remove-redundant-load.ll =================================================================== --- /dev/null +++ test/Analysis/MemoryDependenceAnalysis/memdep-remove-redundant-load.ll @@ -0,0 +1,11 @@ +; RUN: opt -S -memdep -gvn -basicaa < %s | FileCheck %s +; CHECK-LABEL: @test( +; CHECK: %1 = load i32, i32* %Addr1 +; CHECK: store i32 %1, i32* %Addr2 +; CHECK: ret i32 %1 +define i32 @test(i32* %Addr1, i32* %Addr2) { + %1 = load i32, i32* %Addr1 + store i32 %1, i32* %Addr2 + %2 = load i32, i32* %Addr1 + ret i32 %2 +}