[llvm] r348496 - [GVN] Don't perform scalar PRE on GEPs
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 7 10:18:12 PST 2018
Well, it looks like I'm wrong here. As you correctly noted, I should
have provided a test case which broke. When trying to construct one, I
realized that the existing address translation code inside
performLoadPRE handles the case I had in mind. Worse, I took another
look at your patch, and you even call this out in comment form. Sorry
for what was clearly a rushed response in retrospect.
I'm still a bit concerned there's a case we haven't thought of here, but
my level of concern has sharply dropped. Given that, I retract my
request for a revert, and we'll identify any problems which crop up
through normal process.
Philip
On 12/7/18 1:43 AM, Alexandros Lamprineas wrote:
>
> Hi Philip,
>
>
> Thanks for the feedback. If I understand correct this patch prevents
> the PRE of loads in some cases. Could you give me an example (an IR
> reproducer) that demonstrates the problem? Ideally we would want it in
> the llvm regression tests.
>
>
> Cheers,
>
> Alexandros
>
> ------------------------------------------------------------------------
> *From:* Philip Reames <listmail at philipreames.com>
> *Sent:* Thursday, December 6, 2018 8:11:08 PM
> *To:* Alexandros Lamprineas; llvm-commits at lists.llvm.org
> *Subject:* Re: [llvm] r348496 - [GVN] Don't perform scalar PRE on GEPs
> I think this patch is a bad idea and needs to be reverted.
>
> Specifically, this will effectively break all LoadPRE for loads from
> fixed offsets off distinct base objects or where an address is not
> globally available along all relevant paths. The code for LoadPRE
> specifically calls into performScalarPRE for GEPs specifically to make
> this work.
>
> While I understand the desire not to make CGP even more complicated, I
> think this is a case where doing so is called for.
>
> Philip
>
> On 12/6/18 8:11 AM, Alexandros Lamprineas via llvm-commits wrote:
> > Author: alelab01
> > Date: Thu Dec 6 08:11:58 2018
> > New Revision: 348496
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=348496&view=rev
> > Log:
> > [GVN] Don't perform scalar PRE on GEPs
> >
> > Partial Redundancy Elimination of GEPs prevents CodeGenPrepare from
> > sinking the addressing mode computation of memory instructions back
> > to its uses. The problem comes from the insertion of PHIs, which
> > confuse CGP and make it bail.
> >
> > I've autogenerated the check lines of an existing test and added a
> > store instruction to demonstrate the motivation behind this change.
> > The store is now using the gep instead of a phi.
> >
> > Differential Revision: https://reviews.llvm.org/D55009
> >
> > Modified:
> > llvm/trunk/lib/Transforms/Scalar/GVN.cpp
> > llvm/trunk/test/Transforms/GVN/PRE/pre-gep-load.ll
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=348496&r1=348495&r2=348496&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Thu Dec 6 08:11:58 2018
> > @@ -2156,6 +2156,16 @@ bool GVN::performScalarPRE(Instruction *
> > if (isa<CmpInst>(CurInst))
> > return false;
> >
> > + // Don't do PRE on GEPs. The inserted PHI would prevent
> CodeGenPrepare from
> > + // sinking the addressing mode computation back to its uses.
> Extending the
> > + // GEP's live range increases the register pressure, and
> therefore it can
> > + // introduce unnecessary spills.
> > + //
> > + // This doesn't prevent Load PRE. PHI translation will make the
> GEP available
> > + // to the load by moving it to the predecessor block if necessary.
> > + if (isa<GetElementPtrInst>(CurInst))
> > + return false;
> > +
> > // We don't currently value number ANY inline asm calls.
> > if (CallInst *CallI = dyn_cast<CallInst>(CurInst))
> > if (CallI->isInlineAsm())
> >
> > Modified: llvm/trunk/test/Transforms/GVN/PRE/pre-gep-load.ll
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/PRE/pre-gep-load.ll?rev=348496&r1=348495&r2=348496&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/test/Transforms/GVN/PRE/pre-gep-load.ll (original)
> > +++ llvm/trunk/test/Transforms/GVN/PRE/pre-gep-load.ll Thu Dec 6
> 08:11:58 2018
> > @@ -1,3 +1,4 @@
> > +; NOTE: Assertions have been autogenerated by
> utils/update_test_checks.py
> > ; RUN: opt < %s -basicaa -gvn -enable-load-pre -S | FileCheck %s
> > ; RUN: opt < %s -aa-pipeline=basic-aa -passes=gvn -enable-load-pre
> -S | FileCheck %s
> >
> > @@ -6,11 +7,49 @@ target triple = "aarch64--linux-gnu"
> >
> > define double @foo(i32 %stat, i32 %i, double** %p) {
> > ; CHECK-LABEL: @foo(
> > +; CHECK-NEXT: entry:
> > +; CHECK-NEXT: switch i32 [[STAT:%.*]], label [[SW_DEFAULT:%.*]] [
> > +; CHECK-NEXT: i32 0, label [[SW_BB:%.*]]
> > +; CHECK-NEXT: i32 1, label [[SW_BB]]
> > +; CHECK-NEXT: i32 2, label [[ENTRY_SW_BB2_CRIT_EDGE:%.*]]
> > +; CHECK-NEXT: ]
> > +; CHECK: entry.sw.bb2_crit_edge:
> > +; CHECK-NEXT: [[DOTPRE:%.*]] = load double*, double** [[P:%.*]],
> align 8
> > +; CHECK-NEXT: [[DOTPRE1:%.*]] = sext i32 [[I:%.*]] to i64
> > +; CHECK-NEXT: [[ARRAYIDX5_PHI_TRANS_INSERT:%.*]] = getelementptr
> inbounds double, double* [[DOTPRE]], i64 [[DOTPRE1]]
> > +; CHECK-NEXT: [[DOTPRE2:%.*]] = load double, double*
> [[ARRAYIDX5_PHI_TRANS_INSERT]], align 8
> > +; CHECK-NEXT: br label [[SW_BB2:%.*]]
> > +; CHECK: sw.bb:
> > +; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64
> > +; CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[P]], align 8
> > +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double,
> double* [[TMP0]], i64 [[IDXPROM]]
> > +; CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[ARRAYIDX1]],
> align 8
> > +; CHECK-NEXT: [[SUB:%.*]] = fsub double [[TMP1]], 1.000000e+00
> > +; CHECK-NEXT: [[CMP:%.*]] = fcmp olt double [[SUB]], 0.000000e+00
> > +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> > +; CHECK: if.then:
> > +; CHECK-NEXT: br label [[RETURN:%.*]]
> > +; CHECK: if.end:
> > +; CHECK-NEXT: br label [[SW_BB2]]
> > +; CHECK: sw.bb2:
> > +; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE2]],
> [[ENTRY_SW_BB2_CRIT_EDGE]] ], [ [[TMP1]], [[IF_END]] ]
> > +; CHECK-NEXT: [[IDXPROM3_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE1]],
> [[ENTRY_SW_BB2_CRIT_EDGE]] ], [ [[IDXPROM]], [[IF_END]] ]
> > +; CHECK-NEXT: [[TMP3:%.*]] = phi double* [ [[DOTPRE]],
> [[ENTRY_SW_BB2_CRIT_EDGE]] ], [ [[TMP0]], [[IF_END]] ]
> > +; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds double,
> double* [[TMP3]], i64 [[IDXPROM3_PRE_PHI]]
> > +; CHECK-NEXT: [[SUB6:%.*]] = fsub double 3.000000e+00, [[TMP2]]
> > +; CHECK-NEXT: store double [[SUB6]], double* [[ARRAYIDX5]]
> > +; CHECK-NEXT: br label [[RETURN]]
> > +; CHECK: sw.default:
> > +; CHECK-NEXT: br label [[RETURN]]
> > +; CHECK: return:
> > +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi double [ 0.000000e+00,
> [[SW_DEFAULT]] ], [ [[SUB6]], [[SW_BB2]] ], [ [[SUB]], [[IF_THEN]] ]
> > +; CHECK-NEXT: ret double [[RETVAL_0]]
> > +;
> > entry:
> > switch i32 %stat, label %sw.default [
> > - i32 0, label %sw.bb
> > - i32 1, label %sw.bb
> > - i32 2, label %sw.bb2
> > + i32 0, label %sw.bb
> > + i32 1, label %sw.bb
> > + i32 2, label %sw.bb2
> > ]
> >
> > sw.bb: ; preds = %entry, %entry
> > @@ -35,11 +74,8 @@ sw.bb2:
> > %2 = load double*, double** %arrayidx4, align 8
> > %arrayidx5 = getelementptr inbounds double, double* %2, i64
> %idxprom3
> > %3 = load double, double* %arrayidx5, align 8
> > -; CHECK: sw.bb2:
> > -; CHECK-NOT: sext
> > -; CHECK: phi double [
> > -; CHECK-NOT: load
> > %sub6 = fsub double 3.000000e+00, %3
> > + store double %sub6, double* %arrayidx5
> > br label %return
> >
> > sw.default: ; preds = %entry
> > @@ -55,12 +91,24 @@ return:
> > ; actually processed. Make sure we can deal with the situation.
> >
> > define void @test_shortcut_safe(i1 %tst, i32 %p1, i32* %a) {
> > -; CHECK-LABEL: define void @test_shortcut_safe
> > -; CHECK: [[SEXT1:%.*]] = sext i32 %p1 to i64
> > -; CHECK: [[PHI1:%.*]] = phi i64 [ [[SEXT1]], {{%.*}} ], [
> [[PHI2:%.*]], {{%.*}} ]
> > -; CHECK: [[SEXT2:%.*]] = sext i32 %p1 to i64
> > -; CHECK: [[PHI2]] = phi i64 [ [[SEXT2]], {{.*}} ], [ [[PHI1]],
> {{%.*}} ]
> > -; CHECK: getelementptr inbounds i32, i32* %a, i64 [[PHI2]]
> > +; CHECK-LABEL: @test_shortcut_safe(
> > +; CHECK-NEXT: br i1 [[TST:%.*]], label [[SEXT1:%.*]], label
> [[DOTPRE_DEST_CRIT_EDGE:%.*]]
> > +; CHECK: .pre.dest_crit_edge:
> > +; CHECK-NEXT: [[DOTPRE1:%.*]] = sext i32 [[P1:%.*]] to i64
> > +; CHECK-NEXT: br label [[PRE_DEST:%.*]]
> > +; CHECK: pre.dest:
> > +; CHECK-NEXT: [[DOTPRE_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE1]],
> [[DOTPRE_DEST_CRIT_EDGE]] ], [ [[IDXPROM2_PRE_PHI:%.*]],
> [[SEXT_USE:%.*]] ]
> > +; CHECK-NEXT: br label [[SEXT_USE]]
> > +; CHECK: sext1:
> > +; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[P1]] to i64
> > +; CHECK-NEXT: br label [[SEXT_USE]]
> > +; CHECK: sext.use:
> > +; CHECK-NEXT: [[IDXPROM2_PRE_PHI]] = phi i64 [ [[IDXPROM]],
> [[SEXT1]] ], [ [[DOTPRE_PRE_PHI]], [[PRE_DEST]] ]
> > +; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i32,
> i32* [[A:%.*]], i64 [[IDXPROM2_PRE_PHI]]
> > +; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[ARRAYIDX3]], align 4
> > +; CHECK-NEXT: tail call void @g(i32 [[VAL]])
> > +; CHECK-NEXT: br label [[PRE_DEST]]
> > +;
> >
> > br i1 %tst, label %sext1, label %pre.dest
> >
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose
> the contents to any other person, use it for any purpose, or store or
> copy the information in any medium. Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181207/d16fe409/attachment.html>
More information about the llvm-commits
mailing list