From f111607f0606c3ccf13263f7e77e0097bdee904b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 15 Mar 2018 20:30:54 +0000 Subject: [PATCH] [X86] Make sure we use FSUB instruction as the reference for operand order in isAddSubOrSubAdd when recognizing subadd The FADD part of the addsub/subadd pattern can have its operands commuted, but when checking for fsubadd we were using the fadd as reference and commuting the fsub node. llvm-svn: 327660 --- lib/Target/X86/X86ISelLowering.cpp | 16 ++++++++++++---- test/CodeGen/X86/fmsubadd-combine.ll | 24 +++++++++++++++++++----- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 8c681cd4de0..fb871266546 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -30494,10 +30494,18 @@ static bool isAddSubOrSubAdd(SDNode *N, const X86Subtarget &Subtarget, // Ensure that both operations have the same operands. Note that we can // commute the FADD operands. - SDValue LHS = V1->getOperand(0), RHS = V1->getOperand(1); - if ((V2->getOperand(0) != LHS || V2->getOperand(1) != RHS) && - (V2->getOperand(0) != RHS || V2->getOperand(1) != LHS)) - return false; + SDValue LHS, RHS; + if (ExpectedOpcode == ISD::FSUB) { + LHS = V1->getOperand(0); RHS = V1->getOperand(1); + if ((V2->getOperand(0) != LHS || V2->getOperand(1) != RHS) && + (V2->getOperand(0) != RHS || V2->getOperand(1) != LHS)) + return false; + } else { + LHS = V2->getOperand(0); RHS = V2->getOperand(1); + if ((V1->getOperand(0) != LHS || V1->getOperand(1) != RHS) && + (V1->getOperand(0) != RHS || V1->getOperand(1) != LHS)) + return false; + } // We're looking for blends between FADD and FSUB nodes. We insist on these // nodes being lined up in a specific expected pattern. diff --git a/test/CodeGen/X86/fmsubadd-combine.ll b/test/CodeGen/X86/fmsubadd-combine.ll index 20d850306a2..24d18c60791 100644 --- a/test/CodeGen/X86/fmsubadd-combine.ll +++ b/test/CodeGen/X86/fmsubadd-combine.ll @@ -134,14 +134,28 @@ entry: ; This should not be matched to fmsubadd because the mul is on the wrong side of the fsub. define <2 x double> @mul_subadd_bad_commute(<2 x double> %A, <2 x double> %B, <2 x double> %C) #0 { -; FMA3-LABEL: mul_subadd_bad_commute: -; FMA3: # %bb.0: # %entry -; FMA3-NEXT: vfmsubadd213pd {{.*#+}} xmm0 = (xmm1 * xmm0) -/+ xmm2 -; FMA3-NEXT: retq +; FMA3_256-LABEL: mul_subadd_bad_commute: +; FMA3_256: # %bb.0: # %entry +; FMA3_256-NEXT: vmulpd %xmm1, %xmm0, %xmm0 +; FMA3_256-NEXT: vsubpd %xmm0, %xmm2, %xmm1 +; FMA3_256-NEXT: vaddpd %xmm2, %xmm0, %xmm0 +; FMA3_256-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] +; FMA3_256-NEXT: retq +; +; FMA3_512-LABEL: mul_subadd_bad_commute: +; FMA3_512: # %bb.0: # %entry +; FMA3_512-NEXT: vmulpd %xmm1, %xmm0, %xmm0 +; FMA3_512-NEXT: vsubpd %xmm0, %xmm2, %xmm1 +; FMA3_512-NEXT: vaddpd %xmm2, %xmm0, %xmm0 +; FMA3_512-NEXT: vmovsd {{.*#+}} xmm0 = xmm0[0],xmm1[1] +; FMA3_512-NEXT: retq ; ; FMA4-LABEL: mul_subadd_bad_commute: ; FMA4: # %bb.0: # %entry -; FMA4-NEXT: vfmsubaddpd %xmm2, %xmm1, %xmm0, %xmm0 +; FMA4-NEXT: vmulpd %xmm1, %xmm0, %xmm0 +; FMA4-NEXT: vsubpd %xmm0, %xmm2, %xmm1 +; FMA4-NEXT: vaddpd %xmm2, %xmm0, %xmm0 +; FMA4-NEXT: vblendpd {{.*#+}} xmm0 = xmm0[0],xmm1[1] ; FMA4-NEXT: retq entry: %AB = fmul <2 x double> %A, %B