summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2019-09-13 11:22:40 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2019-09-13 11:22:40 +0000
commit930ebc15a6398710e84eea16b735721fe4a2c2fd (patch)
treee24c6467de12aed8174f308ea05e45e2489f055f
parent9eaa981e8efd0a7d2230212e9dbc2ce366bcdbb8 (diff)
downloadbcm5719-llvm-930ebc15a6398710e84eea16b735721fe4a2c2fd.tar.gz
bcm5719-llvm-930ebc15a6398710e84eea16b735721fe4a2c2fd.zip
[X86] negateFMAOpcode - extend to support FMADDSUB/FMSUBADD and output negation. NFCI.
Some prep work for PR42863, this change allows us to move all the FMA opcode mappings into the negateFMAOpcode helper. For the FMADDSUB/FMSUBADD cases, we can only negate the accumulator - any other negations will result in an error. llvm-svn: 371840
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp67
1 files changed, 40 insertions, 27 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 3ca9eea5898..70fd1f69405 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -41819,7 +41819,8 @@ static SDValue isFNEG(SelectionDAG &DAG, SDNode *N) {
return SDValue();
}
-static unsigned negateFMAOpcode(unsigned Opcode, bool NegMul, bool NegAcc) {
+static unsigned negateFMAOpcode(unsigned Opcode, bool NegMul, bool NegAcc,
+ bool NegRes) {
if (NegMul) {
switch (Opcode) {
default: llvm_unreachable("Unexpected opcode");
@@ -41845,6 +41846,24 @@ static unsigned negateFMAOpcode(unsigned Opcode, bool NegMul, bool NegAcc) {
case X86ISD::FNMADD_RND: Opcode = X86ISD::FNMSUB_RND; break;
case X86ISD::FNMSUB: Opcode = X86ISD::FNMADD; break;
case X86ISD::FNMSUB_RND: Opcode = X86ISD::FNMADD_RND; break;
+ case X86ISD::FMADDSUB: Opcode = X86ISD::FMSUBADD; break;
+ case X86ISD::FMADDSUB_RND: Opcode = X86ISD::FMSUBADD_RND; break;
+ case X86ISD::FMSUBADD: Opcode = X86ISD::FMADDSUB; break;
+ case X86ISD::FMSUBADD_RND: Opcode = X86ISD::FMADDSUB_RND; break;
+ }
+ }
+
+ if (NegRes) {
+ switch (Opcode) {
+ default: llvm_unreachable("Unexpected opcode");
+ case ISD::FMA: Opcode = X86ISD::FNMSUB; break;
+ case X86ISD::FMADD_RND: Opcode = X86ISD::FNMSUB_RND; break;
+ case X86ISD::FMSUB: Opcode = X86ISD::FNMADD; break;
+ case X86ISD::FMSUB_RND: Opcode = X86ISD::FNMADD_RND; break;
+ case X86ISD::FNMADD: Opcode = X86ISD::FMSUB; break;
+ case X86ISD::FNMADD_RND: Opcode = X86ISD::FMSUB_RND; break;
+ case X86ISD::FNMSUB: Opcode = ISD::FMA; break;
+ case X86ISD::FNMSUB_RND: Opcode = X86ISD::FMADD_RND; break;
}
}
@@ -41880,25 +41899,24 @@ static SDValue combineFneg(SDNode *N, SelectionDAG &DAG,
// If we're negating an FMA node, then we can adjust the
// instruction to include the extra negation.
- unsigned NewOpcode = 0;
if (Arg.hasOneUse() && Subtarget.hasAnyFMA()) {
switch (Arg.getOpcode()) {
- case ISD::FMA: NewOpcode = X86ISD::FNMSUB; break;
- case X86ISD::FMSUB: NewOpcode = X86ISD::FNMADD; break;
- case X86ISD::FNMADD: NewOpcode = X86ISD::FMSUB; break;
- case X86ISD::FNMSUB: NewOpcode = ISD::FMA; break;
- case X86ISD::FMADD_RND: NewOpcode = X86ISD::FNMSUB_RND; break;
- case X86ISD::FMSUB_RND: NewOpcode = X86ISD::FNMADD_RND; break;
- case X86ISD::FNMADD_RND: NewOpcode = X86ISD::FMSUB_RND; break;
- case X86ISD::FNMSUB_RND: NewOpcode = X86ISD::FMADD_RND; break;
- // We can't handle scalar intrinsic node here because it would only
- // invert one element and not the whole vector. But we could try to handle
- // a negation of the lower element only.
- }
- }
- if (NewOpcode)
- return DAG.getBitcast(OrigVT, DAG.getNode(NewOpcode, DL, VT,
- Arg.getNode()->ops()));
+ case ISD::FMA:
+ case X86ISD::FMSUB:
+ case X86ISD::FNMADD:
+ case X86ISD::FNMSUB:
+ case X86ISD::FMADD_RND:
+ case X86ISD::FMSUB_RND:
+ case X86ISD::FNMADD_RND:
+ case X86ISD::FNMSUB_RND: {
+ // We can't handle scalar intrinsic node here because it would only
+ // invert one element and not the whole vector. But we could try to handle
+ // a negation of the lower element only.
+ unsigned NewOpcode = negateFMAOpcode(Arg.getOpcode(), false, false, true);
+ return DAG.getBitcast(OrigVT, DAG.getNode(NewOpcode, DL, VT, Arg->ops()));
+ }
+ }
+ }
return SDValue();
}
@@ -42877,7 +42895,8 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG,
if (!NegA && !NegB && !NegC)
return SDValue();
- unsigned NewOpcode = negateFMAOpcode(N->getOpcode(), NegA != NegB, NegC);
+ unsigned NewOpcode =
+ negateFMAOpcode(N->getOpcode(), NegA != NegB, NegC, false);
if (N->getNumOperands() == 4)
return DAG.getNode(NewOpcode, dl, VT, A, B, C, N->getOperand(3));
@@ -42885,6 +42904,7 @@ static SDValue combineFMA(SDNode *N, SelectionDAG &DAG,
}
// Combine FMADDSUB(A, B, FNEG(C)) -> FMSUBADD(A, B, C)
+// Combine FMSUBADD(A, B, FNEG(C)) -> FMADDSUB(A, B, C)
static SDValue combineFMADDSUB(SDNode *N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
SDLoc dl(N);
@@ -42898,14 +42918,7 @@ static SDValue combineFMADDSUB(SDNode *N, SelectionDAG &DAG,
if (NegVal.getValueType() != VT)
return SDValue();
- unsigned NewOpcode;
- switch (N->getOpcode()) {
- default: llvm_unreachable("Unexpected opcode!");
- case X86ISD::FMADDSUB: NewOpcode = X86ISD::FMSUBADD; break;
- case X86ISD::FMADDSUB_RND: NewOpcode = X86ISD::FMSUBADD_RND; break;
- case X86ISD::FMSUBADD: NewOpcode = X86ISD::FMADDSUB; break;
- case X86ISD::FMSUBADD_RND: NewOpcode = X86ISD::FMADDSUB_RND; break;
- }
+ unsigned NewOpcode = negateFMAOpcode(N->getOpcode(), false, true, false);
if (N->getNumOperands() == 4)
return DAG.getNode(NewOpcode, dl, VT, N->getOperand(0), N->getOperand(1),
OpenPOWER on IntegriCloud