From 76dfa416156da9fd30e173fb0e97a98c6965bd08 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Mon, 28 Sep 2015 08:02:14 +0000 Subject: [PATCH] [DAGCombine] Fix getStoreMergeAndAliasCandidates's AA-enabled chain walking When AA is being used, non-aliasing stores are canonicalized to use the same chain, and DAGCombiner::getStoreMergeAndAliasCandidates can take advantage of this by looking only as users of a store's chain operand. However, user iteration is not result-number specific, we need to check that the use is as a chain operand, and not via some other operand. It is certainly possible to have another potentially-aliasing store, which shares the first's base pointer, and uses the first's chain's node via some other operand. Failure to catch this situation caused, at least in the included test case, an assert later because the relative sequence-number ordering caused later replacement to create a cycle in the DAG. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248698 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 ++ test/CodeGen/PowerPC/merge-st-chain-op.ll | 41 +++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 test/CodeGen/PowerPC/merge-st-chain-op.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f94f506156c..ec64210667e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10986,6 +10986,8 @@ void DAGCombiner::getStoreMergeAndAliasCandidates( SDValue Chain = St->getChain(); for (auto I = Chain->use_begin(), E = Chain->use_end(); I != E; ++I) { if (StoreSDNode *OtherST = dyn_cast(*I)) { + if (I.getOperandNo() != 0) + continue; if (OtherST->isVolatile() || OtherST->isIndexed()) continue; diff --git a/test/CodeGen/PowerPC/merge-st-chain-op.ll b/test/CodeGen/PowerPC/merge-st-chain-op.ll new file mode 100644 index 00000000000..bfb911c0115 --- /dev/null +++ b/test/CodeGen/PowerPC/merge-st-chain-op.ll @@ -0,0 +1,41 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@_ZNSs4_Rep20_S_empty_rep_storageE = external global [0 x i64], align 8 + +; Function Attrs: nounwind +define void @_ZN5clang7tooling15RefactoringTool10runAndSaveEPNS0_21FrontendActionFactoryE() #0 align 2 { +entry: + br i1 undef, label %_ZN4llvm18IntrusiveRefCntPtrIN5clang13DiagnosticIDsEEC2EPS2_.exit, label %return + +; CHECK: @_ZN5clang7tooling15RefactoringTool10runAndSaveEPNS0_21FrontendActionFactoryE + +_ZN4llvm18IntrusiveRefCntPtrIN5clang13DiagnosticIDsEEC2EPS2_.exit: ; preds = %entry + %call2 = call noalias i8* @_Znwm() #3 + %ref_cnt.i.i = bitcast i8* %call2 to i32* + store <2 x i8*> , <2 x i8*>* undef, align 8 + %IgnoreWarnings.i = getelementptr inbounds i8, i8* %call2, i64 4 + %0 = bitcast i8* %IgnoreWarnings.i to i32* + call void @llvm.memset.p0i8.i64(i8* null, i8 0, i64 48, i32 8, i1 false) #4 + store i32 251658240, i32* %0, align 4 + store i256 37662610426935100959726589394453639584271499769928088551424, i256* null, align 8 + store i32 1, i32* %ref_cnt.i.i, align 4 + unreachable + +return: ; preds = %entry + ret void +} + +; Function Attrs: nobuiltin +declare noalias i8* @_Znwm() #1 + +; Function Attrs: nounwind argmemonly +declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #2 + +attributes #0 = { nounwind "target-cpu"="pwr7" } +attributes #1 = { nobuiltin "target-cpu"="pwr7" } +attributes #2 = { nounwind argmemonly } +attributes #3 = { builtin nounwind } +attributes #4 = { nounwind } + -- 2.34.1