[llvm] r228656 - [x86] Fix PR22524: the DAG combiner was incorrectly handling illegal
Duncan P. N. Exon Smith
dexonsmith at apple.com
Mon Feb 9 19:00:33 PST 2015
Thanks for the quick fix!
> On 2015-Feb-09, at 18:25, Chandler Carruth <chandlerc at gmail.com> wrote:
>
> Author: chandlerc
> Date: Mon Feb 9 20:25:56 2015
> New Revision: 228656
>
> URL: http://llvm.org/viewvc/llvm-project?rev=228656&view=rev
> Log:
> [x86] Fix PR22524: the DAG combiner was incorrectly handling illegal
> nodes when folding bitcasts of constants.
>
> We can't fold things and then check after-the-fact whether it was legal.
> Once we have formed the DAG node, arbitrary other nodes may have been
> collapsed to it. There is no easy way to go back. Instead, we need to
> test for the specific folding cases we're interested in and ensure those
> are legal first.
>
> This could in theory make this less powerful for bitcasting from an
> integer to some vector type, but AFAICT, that can't actually happen in
> the SDAG so its fine. Now, we *only* whitelist specific int->fp and
> fp->int bitcasts for post-legalization folding. I've added the test case
> from the PR.
>
> (Also as a note, this does not appear to be in 3.6, no backport needed)
@Hans: I think Chandler was relying on my bisection from the PR here, but
I had only bisected the opt+llc.ll case. (I first tried to bisect the
llc.ll case, but couldn't find a passing revision.)
I've just checked the llc.ll case on 3.6 (well, slightly old r228165) and
it *does* repro, and cherry-picking this commit fixes it.
Probably not *urgent*, since -instcombine isn't exposing it, but still
seems like a good fix.
@Chandler, I assume you're fine with this going in?
>
>
> Added:
> llvm/trunk/test/CodeGen/X86/constant-combines.ll
> Modified:
> llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=228656&r1=228655&r2=228656&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Mon Feb 9 20:25:56 2015
> @@ -6690,19 +6690,15 @@ SDValue DAGCombiner::visitBITCAST(SDNode
>
> // If the input is a constant, let getNode fold it.
> if (isa<ConstantSDNode>(N0) || isa<ConstantFPSDNode>(N0)) {
> - SDValue Res = DAG.getNode(ISD::BITCAST, SDLoc(N), VT, N0);
> - if (Res.getNode() != N) {
> - if (!LegalOperations ||
> - TLI.isOperationLegal(Res.getNode()->getOpcode(), VT))
> - return Res;
> -
> - // Folding it resulted in an illegal node, and it's too late to
> - // do that. Clean up the old node and forego the transformation.
> - // Ideally this won't happen very often, because instcombine
> - // and the earlier dagcombine runs (where illegal nodes are
> - // permitted) should have folded most of them already.
> - deleteAndRecombine(Res.getNode());
> - }
> + // If we can't allow illegal operations, we need to check that this is just
> + // a fp -> int or int -> conversion and that the resulting operation will
> + // be legal.
> + if (!LegalOperations ||
> + (isa<ConstantSDNode>(N0) && VT.isFloatingPoint() && !VT.isVector() &&
> + TLI.isOperationLegal(ISD::ConstantFP, VT)) ||
> + (isa<ConstantFPSDNode>(N0) && VT.isInteger() && !VT.isVector() &&
> + TLI.isOperationLegal(ISD::Constant, VT)))
> + return DAG.getNode(ISD::BITCAST, SDLoc(N), VT, N0);
> }
>
> // (conv (conv x, t1), t2) -> (conv x, t2)
>
> Added: llvm/trunk/test/CodeGen/X86/constant-combines.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/constant-combines.ll?rev=228656&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/constant-combines.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/constant-combines.ll Mon Feb 9 20:25:56 2015
> @@ -0,0 +1,35 @@
> +; RUN: llc < %s | FileCheck %s
> +
> +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-unknown-unknown"
> +
> +define void @PR22524({ float, float }* %arg) {
> +; Check that we can materialize the zero constants we store in two places here,
> +; and at least form a legal store of the floating point value at the end.
> +; The DAG combiner at one point contained bugs that given enough permutations
> +; would incorrectly form an illegal operation for the last of these stores when
> +; it folded it to a zero too late to legalize the zero store operation. If this
> +; ever starts forming a zero store instead of movss, the test case has stopped
> +; being useful.
> +;
> +; CHECK-LABEL: PR22524:
> +entry:
> + %0 = getelementptr inbounds { float, float }* %arg, i32 0, i32 1
> + store float 0.000000e+00, float* %0, align 4
> +; CHECK: movl $0, 4(%rdi)
> +
> + %1 = getelementptr inbounds { float, float }* %arg, i64 0, i32 0
> + %2 = bitcast float* %1 to i64*
> + %3 = load i64* %2, align 8
> + %4 = trunc i64 %3 to i32
> + %5 = lshr i64 %3, 32
> + %6 = trunc i64 %5 to i32
> + %7 = bitcast i32 %6 to float
> + %8 = fmul float %7, 0.000000e+00
> + %9 = bitcast float* %1 to i32*
> + store i32 %6, i32* %9, align 4
> +; CHECK: movl $0, (%rdi)
> + store float %8, float* %0, align 4
> +; CHECK: movss %{{.*}}, 4(%rdi)
> + ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list