Index: lib/Transforms/Scalar/GVN.cpp =================================================================== --- lib/Transforms/Scalar/GVN.cpp +++ lib/Transforms/Scalar/GVN.cpp @@ -98,6 +98,7 @@ static cl::opt EnablePRE("enable-pre", cl::init(true), cl::Hidden); static cl::opt EnableLoadPRE("enable-load-pre", cl::init(true)); +static cl::opt EnableMemDep("enable-gvn-memdep", cl::init(true)); // Maximum allowed recursion depth. static cl::opt @@ -393,18 +394,13 @@ uint32_t e = assignExpNewValueNum(exp).first; valueNumbering[C] = e; return e; - } else if (AA->onlyReadsMemory(C)) { + } else if (MD && AA->onlyReadsMemory(C)) { Expression exp = createExpr(C); auto ValNum = assignExpNewValueNum(exp); if (ValNum.second) { valueNumbering[C] = ValNum.first; return ValNum.first; } - if (!MD) { - uint32_t e = assignExpNewValueNum(exp).first; - valueNumbering[C] = e; - return e; - } MemDepResult local_dep = MD->getDependency(C); @@ -2520,8 +2516,8 @@ public: static char ID; // Pass identification, replacement for typeid - explicit GVNLegacyPass(bool NoLoads = false) - : FunctionPass(ID), NoLoads(NoLoads) { + explicit GVNLegacyPass(bool NoMemDepAnalysis = !EnableMemDep) + : FunctionPass(ID), NoMemDepAnalysis(NoMemDepAnalysis) { initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry()); } @@ -2536,7 +2532,7 @@ getAnalysis().getDomTree(), getAnalysis().getTLI(), getAnalysis().getAAResults(), - NoLoads ? nullptr + NoMemDepAnalysis ? nullptr : &getAnalysis().getMemDep(), LIWP ? &LIWP->getLoopInfo() : nullptr, &getAnalysis().getORE()); @@ -2546,7 +2542,7 @@ AU.addRequired(); AU.addRequired(); AU.addRequired(); - if (!NoLoads) + if (!NoMemDepAnalysis) AU.addRequired(); AU.addRequired(); @@ -2557,7 +2553,7 @@ } private: - bool NoLoads; + bool NoMemDepAnalysis; GVN Impl; }; @@ -2574,6 +2570,6 @@ INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false) // The public interface to this file... -FunctionPass *llvm::createGVNPass(bool NoLoads) { - return new GVNLegacyPass(NoLoads); +FunctionPass *llvm::createGVNPass(bool NoMemDepAnalysis) { + return new GVNLegacyPass(NoMemDepAnalysis); } Index: test/Transforms/GVN/no-mem-dep-info.ll =================================================================== --- /dev/null +++ test/Transforms/GVN/no-mem-dep-info.ll @@ -0,0 +1,29 @@ +; RUN: opt %s -gvn -S -enable-gvn-memdep=false | FileCheck %s +; RUN: opt %s -gvn -S -enable-gvn-memdep=true | FileCheck %s + +; Check that llvm.x86.avx2.gather.d.ps.256 intrinsic is not eliminated by GVN +; with and without memory dependence info. +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind readonly +declare <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float>, i8*, <8 x i32>, <8 x float>, i8) #0 + +; Function Attrs: nounwind +define <8 x float> @foo1(i8* noalias readonly %arr.ptr, <8 x i32>* noalias readonly %vix.ptr, i8* noalias %t2.ptr) #1 { +allocas: + %vix = load <8 x i32>, <8 x i32>* %vix.ptr, align 4 + %t1.ptr = getelementptr i8, i8* %arr.ptr, i8 4 + + %v1 = tail call <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float> undef, i8* %arr.ptr, <8 x i32> %vix, <8 x float> , i8 1) #2 + store i8 1, i8* %t1.ptr, align 4 + + %v2 = tail call <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float> undef, i8* %arr.ptr, <8 x i32> %vix, <8 x float> , i8 1) #2 + %res = fadd <8 x float> %v1, %v2 + + ret <8 x float> %res +} +; CHECK: foo1 +; CHECK: llvm.x86.avx2.gather.d.ps.256 +; CHECK: store +; CHECK: llvm.x86.avx2.gather.d.ps.256