From: Roman Lebedev Date: Sat, 5 May 2018 15:45:40 +0000 (+0000) Subject: [DAGCombiner] Masked merge: don't touch "not" xor's. X-Git-Tag: android-x86-7.1-r4~1451 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=fe26f48c1eb7024df1d0a6a39b17c807620429db;p=android-x86%2Fexternal-llvm.git [DAGCombiner] Masked merge: don't touch "not" xor's. Summary: Split off form D46031. It seems we don't want to transform the pattern if the `xor`'s are actually `not`'s. In vector case, this breaks `andnpd` / `vandnps` patterns. That being said, we may want to re-visit this `not` handling, maybe in D46073. Reviewers: spatel, craig.topper, javed.absar Reviewed By: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D46492 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331595 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e5ef26f52d3..9bcdcdc1578 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5372,9 +5372,16 @@ SDValue DAGCombiner::MatchLoadCombine(SDNode *N) { // | D | // Into: // (x & m) | (y & ~m) +// NOTE: we don't unfold the pattern if 'xor' is actually a 'not', because at +// the very least that breaks andnpd / andnps patterns, and because those +// patterns are simplified in IR and shouldn't be created in the DAG SDValue DAGCombiner::unfoldMaskedMerge(SDNode *N) { assert(N->getOpcode() == ISD::XOR); + // Don't touch 'not' (i.e. where y = -1). + if (isAllOnesConstantOrAllOnesSplatConstant(N->getOperand(1))) + return SDValue(); + EVT VT = N->getValueType(0); // FIXME @@ -5392,6 +5399,9 @@ SDValue DAGCombiner::unfoldMaskedMerge(SDNode *N) { return false; SDValue Xor0 = Xor.getOperand(0); SDValue Xor1 = Xor.getOperand(1); + // Don't touch 'not' (i.e. where y = -1). + if (isAllOnesConstantOrAllOnesSplatConstant(Xor1)) + return false; if (Other == Xor0) std::swap(Xor0, Xor1); if (Other != Xor1) diff --git a/test/CodeGen/AArch64/unfold-masked-merge-scalar-variablemask.ll b/test/CodeGen/AArch64/unfold-masked-merge-scalar-variablemask.ll index e2d6b4ea098..ff0dfb9ce6a 100644 --- a/test/CodeGen/AArch64/unfold-masked-merge-scalar-variablemask.ll +++ b/test/CodeGen/AArch64/unfold-masked-merge-scalar-variablemask.ll @@ -347,8 +347,8 @@ define i32 @out_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { ; CHECK-LABEL: in_constant_varx_mone: ; CHECK: // %bb.0: -; CHECK-NEXT: and w8, w0, w2 -; CHECK-NEXT: orn w0, w8, w2 +; CHECK-NEXT: bic w8, w2, w0 +; CHECK-NEXT: mvn w0, w8 ; CHECK-NEXT: ret %n0 = xor i32 %x, -1 ; %x %n1 = and i32 %n0, %mask @@ -370,8 +370,9 @@ define i32 @out_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { ; CHECK-LABEL: in_constant_varx_mone_invmask: ; CHECK: // %bb.0: -; CHECK-NEXT: bic w8, w0, w2 -; CHECK-NEXT: orr w0, w8, w2 +; CHECK-NEXT: mvn w8, w0 +; CHECK-NEXT: bic w8, w8, w2 +; CHECK-NEXT: mvn w0, w8 ; CHECK-NEXT: ret %notmask = xor i32 %mask, -1 %n0 = xor i32 %x, -1 ; %x @@ -449,8 +450,8 @@ define i32 @out_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { ; CHECK-LABEL: in_constant_mone_vary: ; CHECK: // %bb.0: -; CHECK-NEXT: bic w8, w1, w2 -; CHECK-NEXT: orr w0, w2, w8 +; CHECK-NEXT: bic w8, w2, w1 +; CHECK-NEXT: eor w0, w8, w1 ; CHECK-NEXT: ret %n0 = xor i32 -1, %y ; %x %n1 = and i32 %n0, %mask @@ -472,8 +473,9 @@ define i32 @out_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { ; CHECK-LABEL: in_constant_mone_vary_invmask: ; CHECK: // %bb.0: -; CHECK-NEXT: and w8, w1, w2 -; CHECK-NEXT: orn w0, w8, w2 +; CHECK-NEXT: mvn w8, w1 +; CHECK-NEXT: bic w8, w8, w2 +; CHECK-NEXT: eor w0, w8, w1 ; CHECK-NEXT: ret %notmask = xor i32 %mask, -1 %n0 = xor i32 -1, %y ; %x diff --git a/test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll b/test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll index 8e54c4dd806..66ebbc0cd22 100644 --- a/test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll +++ b/test/CodeGen/X86/unfold-masked-merge-scalar-variablemask.ll @@ -570,10 +570,8 @@ define i32 @in_constant_varx_mone(i32 %x, i32 %y, i32 %mask) { ; ; CHECK-BMI-LABEL: in_constant_varx_mone: ; CHECK-BMI: # %bb.0: -; CHECK-BMI-NEXT: andl %edx, %edi -; CHECK-BMI-NEXT: notl %edx -; CHECK-BMI-NEXT: orl %edi, %edx -; CHECK-BMI-NEXT: movl %edx, %eax +; CHECK-BMI-NEXT: andnl %edx, %edi, %eax +; CHECK-BMI-NEXT: notl %eax ; CHECK-BMI-NEXT: retq %n0 = xor i32 %x, -1 ; %x %n1 = and i32 %n0, %mask @@ -612,8 +610,9 @@ define i32 @in_constant_varx_mone_invmask(i32 %x, i32 %y, i32 %mask) { ; ; CHECK-BMI-LABEL: in_constant_varx_mone_invmask: ; CHECK-BMI: # %bb.0: -; CHECK-BMI-NEXT: andnl %edi, %edx, %eax -; CHECK-BMI-NEXT: orl %edx, %eax +; CHECK-BMI-NEXT: notl %edx +; CHECK-BMI-NEXT: andnl %edx, %edi, %eax +; CHECK-BMI-NEXT: notl %eax ; CHECK-BMI-NEXT: retq %notmask = xor i32 %mask, -1 %n0 = xor i32 %x, -1 ; %x @@ -743,8 +742,8 @@ define i32 @in_constant_mone_vary(i32 %x, i32 %y, i32 %mask) { ; ; CHECK-BMI-LABEL: in_constant_mone_vary: ; CHECK-BMI: # %bb.0: -; CHECK-BMI-NEXT: andnl %esi, %edx, %eax -; CHECK-BMI-NEXT: orl %edx, %eax +; CHECK-BMI-NEXT: andnl %edx, %esi, %eax +; CHECK-BMI-NEXT: xorl %esi, %eax ; CHECK-BMI-NEXT: retq %n0 = xor i32 -1, %y ; %x %n1 = and i32 %n0, %mask @@ -785,10 +784,9 @@ define i32 @in_constant_mone_vary_invmask(i32 %x, i32 %y, i32 %mask) { ; ; CHECK-BMI-LABEL: in_constant_mone_vary_invmask: ; CHECK-BMI: # %bb.0: -; CHECK-BMI-NEXT: andl %edx, %esi ; CHECK-BMI-NEXT: notl %edx -; CHECK-BMI-NEXT: orl %esi, %edx -; CHECK-BMI-NEXT: movl %edx, %eax +; CHECK-BMI-NEXT: andnl %edx, %esi, %eax +; CHECK-BMI-NEXT: xorl %esi, %eax ; CHECK-BMI-NEXT: retq %notmask = xor i32 %mask, -1 %n0 = xor i32 -1, %y ; %x