[llvm] 7a001a2 - [PowerPC] Require nsz flag for c-a*b to FNMSUB
Qiu Chaofan via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 01:41:39 PDT 2020
Author: Qiu Chaofan
Date: 2020-06-04T16:41:27+08:00
New Revision: 7a001a2d92a777de196eaaa070a4bfc23f40fd87
URL: https://github.com/llvm/llvm-project/commit/7a001a2d92a777de196eaaa070a4bfc23f40fd87
DIFF: https://github.com/llvm/llvm-project/commit/7a001a2d92a777de196eaaa070a4bfc23f40fd87.diff
LOG: [PowerPC] Require nsz flag for c-a*b to FNMSUB
On PowerPC, FNMSUB (both VSX and non-VSX version) means -(a*b-c). But
the backend used to generate these instructions regardless whether nsz
flag exists or not. If a*b-c==0, such transformation changes sign of
zero.
This patch introduces PPC specific FNMSUB ISD opcode, which may help
improving combined FMA code sequence.
Reviewed By: steven.zhang
Differential Revision: https://reviews.llvm.org/D76585
Added:
Modified:
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/lib/Target/PowerPC/PPCISelLowering.h
llvm/lib/Target/PowerPC/PPCInstrInfo.td
llvm/lib/Target/PowerPC/PPCInstrVSX.td
llvm/test/CodeGen/PowerPC/combine-fneg.ll
llvm/test/CodeGen/PowerPC/f128-fma.ll
llvm/test/CodeGen/PowerPC/fdiv.ll
llvm/test/CodeGen/PowerPC/fma-assoc.ll
llvm/test/CodeGen/PowerPC/fma-combine.ll
llvm/test/CodeGen/PowerPC/fma-ext.ll
llvm/test/CodeGen/PowerPC/fma-negate.ll
llvm/test/CodeGen/PowerPC/fma-precision.ll
llvm/test/CodeGen/PowerPC/fma.ll
llvm/test/CodeGen/PowerPC/recipest.ll
llvm/test/CodeGen/PowerPC/repeated-fp-divisors.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 2b69c2d86bc0..ddff7abdbd1f 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1228,6 +1228,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setTargetDAGCombine(ISD::SRA);
setTargetDAGCombine(ISD::SRL);
setTargetDAGCombine(ISD::MUL);
+ setTargetDAGCombine(ISD::FMA);
setTargetDAGCombine(ISD::SINT_TO_FP);
setTargetDAGCombine(ISD::BUILD_VECTOR);
if (Subtarget.hasFPCVT())
@@ -1532,6 +1533,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::FP_EXTEND_HALF: return "PPCISD::FP_EXTEND_HALF";
case PPCISD::MAT_PCREL_ADDR: return "PPCISD::MAT_PCREL_ADDR";
case PPCISD::LD_SPLAT: return "PPCISD::LD_SPLAT";
+ case PPCISD::FNMSUB: return "PPCISD::FNMSUB";
}
return nullptr;
}
@@ -14115,6 +14117,9 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
return combineSRL(N, DCI);
case ISD::MUL:
return combineMUL(N, DCI);
+ case ISD::FMA:
+ case PPCISD::FNMSUB:
+ return combineFMALike(N, DCI);
case PPCISD::SHL:
if (isNullConstant(N->getOperand(0))) // 0 << V -> 0.
return N->getOperand(0);
@@ -15779,6 +15784,85 @@ PPCTargetLowering::createFastISel(FunctionLoweringInfo &FuncInfo,
return PPC::createFastISel(FuncInfo, LibInfo);
}
+// 'Inverted' means the FMA opcode after negating one multiplicand.
+// For example, (fma -a b c) = (fnmsub a b c)
+static unsigned invertFMAOpcode(unsigned Opc) {
+ switch (Opc) {
+ default:
+ llvm_unreachable("Invalid FMA opcode for PowerPC!");
+ case ISD::FMA:
+ return PPCISD::FNMSUB;
+ case PPCISD::FNMSUB:
+ return ISD::FMA;
+ }
+}
+
+SDValue PPCTargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG,
+ bool LegalOps, bool OptForSize,
+ NegatibleCost &Cost,
+ unsigned Depth) const {
+ if (Depth > SelectionDAG::MaxRecursionDepth)
+ return SDValue();
+
+ unsigned Opc = Op.getOpcode();
+ EVT VT = Op.getValueType();
+ SDNodeFlags Flags = Op.getNode()->getFlags();
+
+ switch (Opc) {
+ case PPCISD::FNMSUB:
+ // TODO: QPX subtarget is deprecated. No transformation here.
+ if (!Op.hasOneUse() || !isTypeLegal(VT) || Subtarget.hasQPX())
+ break;
+
+ const TargetOptions &Options = getTargetMachine().Options;
+ SDValue N0 = Op.getOperand(0);
+ SDValue N1 = Op.getOperand(1);
+ SDValue N2 = Op.getOperand(2);
+ SDLoc Loc(Op);
+
+ NegatibleCost N2Cost = NegatibleCost::Expensive;
+ SDValue NegN2 =
+ getNegatedExpression(N2, DAG, LegalOps, OptForSize, N2Cost, Depth + 1);
+
+ if (!NegN2)
+ return SDValue();
+
+ // (fneg (fnmsub a b c)) => (fnmsub (fneg a) b (fneg c))
+ // (fneg (fnmsub a b c)) => (fnmsub a (fneg b) (fneg c))
+ // These transformations may change sign of zeroes. For example,
+ // -(-ab-(-c))=-0 while -(-(ab-c))=+0 when a=b=c=1.
+ if (Flags.hasNoSignedZeros() || Options.NoSignedZerosFPMath) {
+ // Try and choose the cheaper one to negate.
+ NegatibleCost N0Cost = NegatibleCost::Expensive;
+ SDValue NegN0 = getNegatedExpression(N0, DAG, LegalOps, OptForSize,
+ N0Cost, Depth + 1);
+
+ NegatibleCost N1Cost = NegatibleCost::Expensive;
+ SDValue NegN1 = getNegatedExpression(N1, DAG, LegalOps, OptForSize,
+ N1Cost, Depth + 1);
+
+ if (NegN0 && N0Cost <= N1Cost) {
+ Cost = std::min(N0Cost, N2Cost);
+ return DAG.getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
+ } else if (NegN1) {
+ Cost = std::min(N1Cost, N2Cost);
+ return DAG.getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
+ }
+ }
+
+ // (fneg (fnmsub a b c)) => (fma a b (fneg c))
+ if (isOperationLegal(ISD::FMA, VT)) {
+ Cost = N2Cost;
+ return DAG.getNode(ISD::FMA, Loc, VT, N0, N1, NegN2, Flags);
+ }
+
+ break;
+ }
+
+ return TargetLowering::getNegatedExpression(Op, DAG, LegalOps, OptForSize,
+ Cost, Depth);
+}
+
// Override to enable LOAD_STACK_GUARD lowering on Linux.
bool PPCTargetLowering::useLoadStackGuardNode() const {
if (!Subtarget.isTargetLinux())
@@ -16185,6 +16269,45 @@ SDValue PPCTargetLowering::combineMUL(SDNode *N, DAGCombinerInfo &DCI) const {
}
}
+// Combine fma-like op (like fnmsub) with fnegs to appropriate op. Do this
+// in combiner since we need to check SD flags and other subtarget features.
+SDValue PPCTargetLowering::combineFMALike(SDNode *N,
+ DAGCombinerInfo &DCI) const {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ SDNodeFlags Flags = N->getFlags();
+ EVT VT = N->getValueType(0);
+ SelectionDAG &DAG = DCI.DAG;
+ const TargetOptions &Options = getTargetMachine().Options;
+ unsigned Opc = N->getOpcode();
+ bool CodeSize = DAG.getMachineFunction().getFunction().hasOptSize();
+ bool LegalOps = !DCI.isBeforeLegalizeOps();
+ SDLoc Loc(N);
+
+ // TODO: QPX subtarget is deprecated. No transformation here.
+ if (Subtarget.hasQPX() || !isOperationLegal(ISD::FMA, VT) ||
+ (VT.isVector() && !Subtarget.hasVSX()))
+ return SDValue();
+
+ // Allowing transformation to FNMSUB may change sign of zeroes when ab-c=0
+ // since (fnmsub a b c)=-0 while c-ab=+0.
+ if (!Flags.hasNoSignedZeros() && !Options.NoSignedZerosFPMath)
+ return SDValue();
+
+ // (fma (fneg a) b c) => (fnmsub a b c)
+ // (fnmsub (fneg a) b c) => (fma a b c)
+ if (SDValue NegN0 = getCheaperNegatedExpression(N0, DAG, LegalOps, CodeSize))
+ return DAG.getNode(invertFMAOpcode(Opc), Loc, VT, NegN0, N1, N2, Flags);
+
+ // (fma a (fneg b) c) => (fnmsub a b c)
+ // (fnmsub a (fneg b) c) => (fma a b c)
+ if (SDValue NegN1 = getCheaperNegatedExpression(N1, DAG, LegalOps, CodeSize))
+ return DAG.getNode(invertFMAOpcode(Opc), Loc, VT, N0, NegN1, N2, Flags);
+
+ return SDValue();
+}
+
bool PPCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
// Only duplicate to increase tail-calls for the 64bit SysV ABIs.
if (!Subtarget.is64BitELFABI())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index f3efd26f2d3a..e47ab864c142 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -148,6 +148,9 @@ namespace llvm {
SRA,
SHL,
+ /// FNMSUB - Negated multiply-subtract instruction.
+ FNMSUB,
+
/// EXTSWSLI = The PPC extswsli instruction, which does an extend-sign
/// word and shift left immediate.
EXTSWSLI,
@@ -674,6 +677,10 @@ namespace llvm {
return VT.isScalarInteger();
}
+ SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps,
+ bool OptForSize, NegatibleCost &Cost,
+ unsigned Depth = 0) const override;
+
/// getSetCCResultType - Return the ISD::SETCC ValueType
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
EVT VT) const override;
@@ -1202,6 +1209,7 @@ namespace llvm {
SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineADD(SDNode *N, DAGCombinerInfo &DCI) const;
+ SDValue combineFMALike(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const;
SDValue combineABS(SDNode *N, DAGCombinerInfo &DCI) const;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 4825465d8e1e..cab985cefa0c 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -216,6 +216,8 @@ def PPCsrl : SDNode<"PPCISD::SRL" , SDTIntShiftOp>;
def PPCsra : SDNode<"PPCISD::SRA" , SDTIntShiftOp>;
def PPCshl : SDNode<"PPCISD::SHL" , SDTIntShiftOp>;
+def PPCfnmsub : SDNode<"PPCISD::FNMSUB" , SDTFPTernaryOp>;
+
def PPCextswsli : SDNode<"PPCISD::EXTSWSLI" , SDT_PPCextswsli>;
// Move 2 i64 values into a VSX register
@@ -3381,15 +3383,19 @@ def : Pat<(atomic_fence (timm), (timm)), (SYNC 1)>, Requires<[HasSYNC]>;
def : Pat<(atomic_fence (timm), (timm)), (MSYNC)>, Requires<[HasOnlyMSYNC]>;
let Predicates = [HasFPU] in {
-// Additional FNMSUB patterns: -a*c + b == -(a*c - b)
-def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
- (FNMSUB $A, $C, $B)>;
-def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B),
- (FNMSUB $A, $C, $B)>;
-def : Pat<(fma (fneg f32:$A), f32:$C, f32:$B),
- (FNMSUBS $A, $C, $B)>;
-def : Pat<(fma f32:$A, (fneg f32:$C), f32:$B),
- (FNMSUBS $A, $C, $B)>;
+// Additional fnmsub patterns for custom node
+def : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
+ (FNMSUB $A, $B, $C)>;
+def : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
+ (FNMSUBS $A, $B, $C)>;
+def : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
+ (FMSUB $A, $B, $C)>;
+def : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
+ (FMSUBS $A, $B, $C)>;
+def : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
+ (FNMADD $A, $B, $C)>;
+def : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
+ (FNMADDS $A, $B, $C)>;
// FCOPYSIGN's operand types need not agree.
def : Pat<(fcopysign f64:$frB, f32:$frA),
diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
index acb8e3563ffb..67a76bc7c32b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
@@ -2416,21 +2416,27 @@ def : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A),
(and v4i32:$B, v4i32:$C))),
(v4i32 (XXSEL $A, $B, $C))>;
-// Additional fnmsub patterns: -a*b + c == -(a*b - c)
-def : Pat<(fma (fneg f64:$A), f64:$B, f64:$C),
- (XSNMSUBADP $C, $A, $B)>;
-def : Pat<(fma f64:$A, (fneg f64:$B), f64:$C),
+// Additional fnmsub pattern for PPC specific ISD opcode
+def : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
(XSNMSUBADP $C, $A, $B)>;
+def : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
+ (XSMSUBADP $C, $A, $B)>;
+def : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
+ (XSNMADDADP $C, $A, $B)>;
-def : Pat<(fma (fneg v2f64:$A), v2f64:$B, v2f64:$C),
- (XVNMSUBADP $C, $A, $B)>;
-def : Pat<(fma v2f64:$A, (fneg v2f64:$B), v2f64:$C),
+def : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C),
(XVNMSUBADP $C, $A, $B)>;
+def : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)),
+ (XVMSUBADP $C, $A, $B)>;
+def : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)),
+ (XVNMADDADP $C, $A, $B)>;
-def : Pat<(fma (fneg v4f32:$A), v4f32:$B, v4f32:$C),
- (XVNMSUBASP $C, $A, $B)>;
-def : Pat<(fma v4f32:$A, (fneg v4f32:$B), v4f32:$C),
+def : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C),
(XVNMSUBASP $C, $A, $B)>;
+def : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
+ (XVMSUBASP $C, $A, $B)>;
+def : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
+ (XVNMADDASP $C, $A, $B)>;
def : Pat<(v2f64 (bitconvert v4f32:$A)),
(COPY_TO_REGCLASS $A, VSRC)>;
@@ -3003,11 +3009,13 @@ def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
(SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
-// Additional xsnmsubasp patterns: -a*b + c == -(a*b - c)
-def : Pat<(fma (fneg f32:$A), f32:$B, f32:$C),
- (XSNMSUBASP $C, $A, $B)>;
-def : Pat<(fma f32:$A, (fneg f32:$B), f32:$C),
+// Additional fnmsub pattern for PPC specific ISD opcode
+def : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
(XSNMSUBASP $C, $A, $B)>;
+def : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
+ (XSMSUBASP $C, $A, $B)>;
+def : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
+ (XSNMADDASP $C, $A, $B)>;
// f32 neg
// Although XSNEGDP is available in P7, we want to select it starting from P8,
@@ -3516,9 +3524,13 @@ def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
// Any Power9 VSX subtarget.
let Predicates = [HasVSX, HasP9Vector] in {
-// Additional fnmsub patterns: -a*b + c == -(a*b - c)
-def : Pat<(fma (fneg f128:$A), f128:$B, f128:$C), (XSNMSUBQP $C, $A, $B)>;
-def : Pat<(fma f128:$A, (fneg f128:$B), f128:$C), (XSNMSUBQP $C, $A, $B)>;
+// Additional fnmsub pattern for PPC specific ISD opcode
+def : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C),
+ (XSNMSUBQP $C, $A, $B)>;
+def : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
+ (XSMSUBQP $C, $A, $B)>;
+def : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
+ (XSNMADDQP $C, $A, $B)>;
def : Pat<(f128 (sint_to_fp i64:$src)),
(f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
diff --git a/llvm/test/CodeGen/PowerPC/combine-fneg.ll b/llvm/test/CodeGen/PowerPC/combine-fneg.ll
index 11af9835bc38..65e884483a3c 100644
--- a/llvm/test/CodeGen/PowerPC/combine-fneg.ll
+++ b/llvm/test/CodeGen/PowerPC/combine-fneg.ll
@@ -13,10 +13,10 @@ define <4 x double> @fneg_fdiv_splat(double %a0, <4 x double> %a1) {
; CHECK-NEXT: xvredp 2, 0
; CHECK-NEXT: xxswapd 1, 1
; CHECK-NEXT: xxlor 3, 1, 1
-; CHECK-NEXT: xvmaddadp 3, 0, 2
-; CHECK-NEXT: xvnmsubadp 2, 2, 3
-; CHECK-NEXT: xvmaddadp 1, 0, 2
-; CHECK-NEXT: xvmsubadp 2, 2, 1
+; CHECK-NEXT: xvnmsubadp 3, 0, 2
+; CHECK-NEXT: xvmaddadp 2, 2, 3
+; CHECK-NEXT: xvnmsubadp 1, 0, 2
+; CHECK-NEXT: xvnmaddadp 2, 2, 1
; CHECK-NEXT: xvmuldp 34, 34, 2
; CHECK-NEXT: xvmuldp 35, 35, 2
; CHECK-NEXT: blr
diff --git a/llvm/test/CodeGen/PowerPC/f128-fma.ll b/llvm/test/CodeGen/PowerPC/f128-fma.ll
index 8bd2ffe03e58..8f76520d32bd 100644
--- a/llvm/test/CodeGen/PowerPC/f128-fma.ll
+++ b/llvm/test/CodeGen/PowerPC/f128-fma.ll
@@ -121,7 +121,7 @@ entry:
%1 = load fp128, fp128* %b, align 16
%2 = load fp128, fp128* %c, align 16
%mul = fmul contract fp128 %1, %2
- %sub = fsub contract fp128 %0, %mul
+ %sub = fsub contract nsz fp128 %0, %mul
store fp128 %sub, fp128* %res, align 16
ret void
; CHECK-LABEL: qpFmsub
diff --git a/llvm/test/CodeGen/PowerPC/fdiv.ll b/llvm/test/CodeGen/PowerPC/fdiv.ll
index 96b737944c2d..b2004fe471b8 100644
--- a/llvm/test/CodeGen/PowerPC/fdiv.ll
+++ b/llvm/test/CodeGen/PowerPC/fdiv.ll
@@ -10,6 +10,6 @@ define dso_local float @foo(float %0, float %1) local_unnamed_addr {
; CHECK-NEXT: xsmaddasp 0, 3, 1
; CHECK-NEXT: fmr 1, 0
; CHECK-NEXT: blr
- %3 = fdiv reassoc arcp float %0, %1
+ %3 = fdiv reassoc arcp nsz float %0, %1
ret float %3
}
diff --git a/llvm/test/CodeGen/PowerPC/fma-assoc.ll b/llvm/test/CodeGen/PowerPC/fma-assoc.ll
index b5a839f3485d..f853e49ab12c 100644
--- a/llvm/test/CodeGen/PowerPC/fma-assoc.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-assoc.ll
@@ -225,14 +225,18 @@ define double @test_FMSUB_ASSOC_EXT2(float %A, float %B, float %C,
define double @test_FMSUB_ASSOC_EXT3(float %A, float %B, double %C,
; CHECK-LABEL: test_FMSUB_ASSOC_EXT3:
; CHECK: # %bb.0:
-; CHECK-NEXT: fnmsub 0, 1, 2, 5
-; CHECK-NEXT: fnmsub 1, 3, 4, 0
+; CHECK-NEXT: fneg 0, 1
+; CHECK-NEXT: fmadd 0, 0, 2, 5
+; CHECK-NEXT: fneg 1, 3
+; CHECK-NEXT: fmadd 1, 1, 4, 0
; CHECK-NEXT: blr
;
; CHECK-VSX-LABEL: test_FMSUB_ASSOC_EXT3:
; CHECK-VSX: # %bb.0:
-; CHECK-VSX-NEXT: xsnmsubmdp 1, 2, 5
-; CHECK-VSX-NEXT: xsnmsubadp 1, 3, 4
+; CHECK-VSX-NEXT: xsnegdp 1, 1
+; CHECK-VSX-NEXT: xsnegdp 0, 3
+; CHECK-VSX-NEXT: xsmaddmdp 1, 2, 5
+; CHECK-VSX-NEXT: xsmaddadp 1, 0, 4
; CHECK-VSX-NEXT: blr
double %D, double %E) {
%F = fmul float %A, %B ; <float> [#uses=1]
@@ -246,15 +250,19 @@ define double @test_FMSUB_ASSOC_EXT3(float %A, float %B, double %C,
define double @test_FMSUB_ASSOC_EXT4(float %A, float %B, float %C,
; CHECK-LABEL: test_FMSUB_ASSOC_EXT4:
; CHECK: # %bb.0:
-; CHECK-NEXT: fnmsub 0, 3, 4, 5
-; CHECK-NEXT: fnmsub 1, 1, 2, 0
+; CHECK-NEXT: fneg 0, 3
+; CHECK-NEXT: fmadd 0, 0, 4, 5
+; CHECK-NEXT: fneg 1, 1
+; CHECK-NEXT: fmadd 1, 1, 2, 0
; CHECK-NEXT: blr
;
; CHECK-VSX-LABEL: test_FMSUB_ASSOC_EXT4:
; CHECK-VSX: # %bb.0:
-; CHECK-VSX-NEXT: xsnmsubmdp 3, 4, 5
-; CHECK-VSX-NEXT: xsnmsubadp 3, 1, 2
-; CHECK-VSX-NEXT: fmr 1, 3
+; CHECK-VSX-NEXT: xsnegdp 0, 3
+; CHECK-VSX-NEXT: xsnegdp 1, 1
+; CHECK-VSX-NEXT: xsmaddmdp 0, 4, 5
+; CHECK-VSX-NEXT: xsmaddadp 0, 1, 2
+; CHECK-VSX-NEXT: fmr 1, 0
; CHECK-VSX-NEXT: blr
float %D, double %E) {
%F = fmul float %A, %B ; <float> [#uses=1]
@@ -503,14 +511,18 @@ define double @test_reassoc_FMSUB_ASSOC_EXT2(float %A, float %B, float %C,
define double @test_reassoc_FMSUB_ASSOC_EXT3(float %A, float %B, double %C,
; CHECK-LABEL: test_reassoc_FMSUB_ASSOC_EXT3:
; CHECK: # %bb.0:
-; CHECK-NEXT: fnmsub 0, 1, 2, 5
-; CHECK-NEXT: fnmsub 1, 3, 4, 0
+; CHECK-NEXT: fneg 0, 1
+; CHECK-NEXT: fmadd 0, 0, 2, 5
+; CHECK-NEXT: fneg 1, 3
+; CHECK-NEXT: fmadd 1, 1, 4, 0
; CHECK-NEXT: blr
;
; CHECK-VSX-LABEL: test_reassoc_FMSUB_ASSOC_EXT3:
; CHECK-VSX: # %bb.0:
-; CHECK-VSX-NEXT: xsnmsubmdp 1, 2, 5
-; CHECK-VSX-NEXT: xsnmsubadp 1, 3, 4
+; CHECK-VSX-NEXT: xsnegdp 1, 1
+; CHECK-VSX-NEXT: xsnegdp 0, 3
+; CHECK-VSX-NEXT: xsmaddmdp 1, 2, 5
+; CHECK-VSX-NEXT: xsmaddadp 1, 0, 4
; CHECK-VSX-NEXT: blr
double %D, double %E) {
%F = fmul reassoc float %A, %B ; <float> [#uses=1]
@@ -521,18 +533,45 @@ define double @test_reassoc_FMSUB_ASSOC_EXT3(float %A, float %B, double %C,
ret double %J
}
+; fnmsub/xsnmsubadp may affect the sign of zero, we need nsz flag
+; to ensure generating them
+define double @test_fast_FMSUB_ASSOC_EXT3(float %A, float %B, double %C,
+; CHECK-LABEL: test_fast_FMSUB_ASSOC_EXT3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fnmsub 0, 1, 2, 5
+; CHECK-NEXT: fnmsub 1, 3, 4, 0
+; CHECK-NEXT: blr
+;
+; CHECK-VSX-LABEL: test_fast_FMSUB_ASSOC_EXT3:
+; CHECK-VSX: # %bb.0:
+; CHECK-VSX-NEXT: xsnmsubmdp 1, 2, 5
+; CHECK-VSX-NEXT: xsnmsubadp 1, 3, 4
+; CHECK-VSX-NEXT: blr
+ double %D, double %E) {
+ %F = fmul reassoc float %A, %B
+ %G = fpext float %F to double
+ %H = fmul reassoc double %C, %D
+ %I = fadd reassoc nsz double %H, %G
+ %J = fsub reassoc nsz double %E, %I
+ ret double %J
+}
+
define double @test_reassoc_FMSUB_ASSOC_EXT4(float %A, float %B, float %C,
; CHECK-LABEL: test_reassoc_FMSUB_ASSOC_EXT4:
; CHECK: # %bb.0:
-; CHECK-NEXT: fnmsub 0, 3, 4, 5
-; CHECK-NEXT: fnmsub 1, 1, 2, 0
+; CHECK-NEXT: fneg 0, 3
+; CHECK-NEXT: fmadd 0, 0, 4, 5
+; CHECK-NEXT: fneg 1, 1
+; CHECK-NEXT: fmadd 1, 1, 2, 0
; CHECK-NEXT: blr
;
; CHECK-VSX-LABEL: test_reassoc_FMSUB_ASSOC_EXT4:
; CHECK-VSX: # %bb.0:
-; CHECK-VSX-NEXT: xsnmsubmdp 3, 4, 5
-; CHECK-VSX-NEXT: xsnmsubadp 3, 1, 2
-; CHECK-VSX-NEXT: fmr 1, 3
+; CHECK-VSX-NEXT: xsnegdp 0, 3
+; CHECK-VSX-NEXT: xsnegdp 1, 1
+; CHECK-VSX-NEXT: xsmaddmdp 0, 4, 5
+; CHECK-VSX-NEXT: xsmaddadp 0, 1, 2
+; CHECK-VSX-NEXT: fmr 1, 0
; CHECK-VSX-NEXT: blr
float %D, double %E) {
%F = fmul reassoc float %A, %B ; <float> [#uses=1]
@@ -542,3 +581,25 @@ define double @test_reassoc_FMSUB_ASSOC_EXT4(float %A, float %B, float %C,
%J = fsub reassoc double %E, %I ; <double> [#uses=1]
ret double %J
}
+
+define double @test_fast_FMSUB_ASSOC_EXT4(float %A, float %B, float %C,
+; CHECK-LABEL: test_fast_FMSUB_ASSOC_EXT4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: fnmsub 0, 3, 4, 5
+; CHECK-NEXT: fnmsub 1, 1, 2, 0
+; CHECK-NEXT: blr
+;
+; CHECK-VSX-LABEL: test_fast_FMSUB_ASSOC_EXT4:
+; CHECK-VSX: # %bb.0:
+; CHECK-VSX-NEXT: xsnmsubmdp 3, 4, 5
+; CHECK-VSX-NEXT: xsnmsubadp 3, 1, 2
+; CHECK-VSX-NEXT: fmr 1, 3
+; CHECK-VSX-NEXT: blr
+ float %D, double %E) {
+ %F = fmul reassoc float %A, %B
+ %G = fmul reassoc float %C, %D
+ %H = fadd reassoc nsz float %F, %G
+ %I = fpext float %H to double
+ %J = fsub reassoc nsz double %E, %I
+ ret double %J
+}
diff --git a/llvm/test/CodeGen/PowerPC/fma-combine.ll b/llvm/test/CodeGen/PowerPC/fma-combine.ll
index f3fc615b5755..6683d925a1b1 100644
--- a/llvm/test/CodeGen/PowerPC/fma-combine.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-combine.ll
@@ -176,9 +176,11 @@ define float @fma_combine_no_ice() {
; CHECK-NEXT: addis 3, 2, .LCPI4_2 at toc@ha
; CHECK-NEXT: lfs 3, .LCPI4_1 at toc@l(4)
; CHECK-NEXT: lfs 1, .LCPI4_2 at toc@l(3)
+; CHECK-NEXT: fmr 4, 3
; CHECK-NEXT: xsmaddasp 3, 2, 0
+; CHECK-NEXT: xsnmaddasp 4, 2, 0
; CHECK-NEXT: xsmaddasp 1, 2, 3
-; CHECK-NEXT: xsnmsubasp 1, 3, 2
+; CHECK-NEXT: xsmaddasp 1, 4, 2
; CHECK-NEXT: blr
%tmp = load float, float* undef, align 4
%tmp2 = load float, float* undef, align 4
diff --git a/llvm/test/CodeGen/PowerPC/fma-ext.ll b/llvm/test/CodeGen/PowerPC/fma-ext.ll
index f8ed49f9ca7c..8bd09375a38a 100644
--- a/llvm/test/CodeGen/PowerPC/fma-ext.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-ext.ll
@@ -49,10 +49,27 @@ define double @test_FMSUB_EXT2(float %A, float %B, double %C) {
%F = fsub double %C, %E ; <double> [#uses=1]
ret double %F
; CHECK-LABEL: test_FMSUB_EXT2:
-; CHECK: fnmsub
+; CHECK: fneg
+; CHECK-NEXT: fmadd
; CHECK-NEXT: blr
; CHECK-VSX-LABEL: test_FMSUB_EXT2:
+; CHECK-VSX: xsnegdp
+; CHECK-VSX-NEXT: xsmaddmdp
+; CHECK-VSX-NEXT: blr
+}
+
+; need nsz flag to generate fnmsub since it may affect sign of zero
+define double @test_FMSUB_EXT2_NSZ(float %A, float %B, double %C) {
+ %D = fmul nsz float %A, %B ; <float> [#uses=1]
+ %E = fpext float %D to double ; <double> [#uses=1]
+ %F = fsub nsz double %C, %E ; <double> [#uses=1]
+ ret double %F
+; CHECK-LABEL: test_FMSUB_EXT2_NSZ:
+; CHECK: fnmsub
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FMSUB_EXT2_NSZ:
; CHECK-VSX: xsnmsubmdp
; CHECK-VSX-NEXT: blr
}
diff --git a/llvm/test/CodeGen/PowerPC/fma-negate.ll b/llvm/test/CodeGen/PowerPC/fma-negate.ll
index 254934d69170..2bdc361ebf3e 100644
--- a/llvm/test/CodeGen/PowerPC/fma-negate.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-negate.ll
@@ -7,12 +7,14 @@
define double @test_mul_sub_f64(double %a, double %b, double %c) {
; VSX-LABEL: test_mul_sub_f64:
; VSX: # %bb.0: # %entry
-; VSX-NEXT: xsnmsubadp 1, 2, 3
+; VSX-NEXT: xsnegdp 0, 2
+; VSX-NEXT: xsmaddadp 1, 0, 3
; VSX-NEXT: blr
;
; NO-VSX-LABEL: test_mul_sub_f64:
; NO-VSX: # %bb.0: # %entry
-; NO-VSX-NEXT: fnmsub 1, 2, 3, 1
+; NO-VSX-NEXT: fneg 0, 2
+; NO-VSX-NEXT: fmadd 1, 0, 3, 1
; NO-VSX-NEXT: blr
entry:
%0 = fmul contract reassoc double %b, %c
@@ -43,13 +45,15 @@ entry:
define double @test_neg_fma_f64(double %a, double %b, double %c) {
; VSX-LABEL: test_neg_fma_f64:
; VSX: # %bb.0: # %entry
-; VSX-NEXT: xsnmsubadp 3, 1, 2
+; VSX-NEXT: xsnegdp 0, 1
+; VSX-NEXT: xsmaddadp 3, 0, 2
; VSX-NEXT: fmr 1, 3
; VSX-NEXT: blr
;
; NO-VSX-LABEL: test_neg_fma_f64:
; NO-VSX: # %bb.0: # %entry
-; NO-VSX-NEXT: fnmsub 1, 1, 2, 3
+; NO-VSX-NEXT: fneg 0, 1
+; NO-VSX-NEXT: fmadd 1, 0, 2, 3
; NO-VSX-NEXT: blr
entry:
%0 = fsub contract reassoc double -0.0, %a
@@ -61,12 +65,14 @@ entry:
define float @test_mul_sub_f32(float %a, float %b, float %c) {
; VSX-LABEL: test_mul_sub_f32:
; VSX: # %bb.0: # %entry
-; VSX-NEXT: xsnmsubasp 1, 2, 3
+; VSX-NEXT: xsnegdp 0, 2
+; VSX-NEXT: xsmaddasp 1, 0, 3
; VSX-NEXT: blr
;
; NO-VSX-LABEL: test_mul_sub_f32:
; NO-VSX: # %bb.0: # %entry
-; NO-VSX-NEXT: fnmsubs 1, 2, 3, 1
+; NO-VSX-NEXT: fneg 0, 2
+; NO-VSX-NEXT: fmadds 1, 0, 3, 1
; NO-VSX-NEXT: blr
entry:
%0 = fmul contract reassoc float %b, %c
@@ -97,13 +103,15 @@ entry:
define float @test_neg_fma_f32(float %a, float %b, float %c) {
; VSX-LABEL: test_neg_fma_f32:
; VSX: # %bb.0: # %entry
-; VSX-NEXT: xsnmsubasp 3, 1, 2
+; VSX-NEXT: xsnegdp 0, 1
+; VSX-NEXT: xsmaddasp 3, 0, 2
; VSX-NEXT: fmr 1, 3
; VSX-NEXT: blr
;
; NO-VSX-LABEL: test_neg_fma_f32:
; NO-VSX: # %bb.0: # %entry
-; NO-VSX-NEXT: fnmsubs 1, 1, 2, 3
+; NO-VSX-NEXT: fneg 0, 1
+; NO-VSX-NEXT: fmadds 1, 0, 2, 3
; NO-VSX-NEXT: blr
entry:
%0 = fsub contract reassoc float -0.0, %a
@@ -114,14 +122,17 @@ entry:
define <2 x double> @test_neg_fma_v2f64(<2 x double> %a, <2 x double> %b,
; VSX-LABEL: test_neg_fma_v2f64:
; VSX: # %bb.0: # %entry
-; VSX-NEXT: xvnmsubadp 36, 34, 35
+; VSX-NEXT: xvnegdp 0, 34
+; VSX-NEXT: xvmaddadp 36, 0, 35
; VSX-NEXT: vmr 2, 4
; VSX-NEXT: blr
;
; NO-VSX-LABEL: test_neg_fma_v2f64:
; NO-VSX: # %bb.0: # %entry
-; NO-VSX-NEXT: fnmsub 1, 1, 3, 5
-; NO-VSX-NEXT: fnmsub 2, 2, 4, 6
+; NO-VSX-NEXT: fneg 0, 2
+; NO-VSX-NEXT: fneg 1, 1
+; NO-VSX-NEXT: fmadd 1, 1, 3, 5
+; NO-VSX-NEXT: fmadd 2, 0, 4, 6
; NO-VSX-NEXT: blr
<2 x double> %c) {
entry:
@@ -135,7 +146,8 @@ entry:
define <4 x float> @test_neg_fma_v4f32(<4 x float> %a, <4 x float> %b,
; VSX-LABEL: test_neg_fma_v4f32:
; VSX: # %bb.0: # %entry
-; VSX-NEXT: xvnmsubasp 36, 34, 35
+; VSX-NEXT: xvnegsp 0, 34
+; VSX-NEXT: xvmaddasp 36, 0, 35
; VSX-NEXT: vmr 2, 4
; VSX-NEXT: blr
;
@@ -167,8 +179,8 @@ define double @test_fast_mul_sub_f64(double %a, double %b, double %c) {
; NO-VSX-NEXT: fnmsub 1, 2, 3, 1
; NO-VSX-NEXT: blr
entry:
- %0 = fmul reassoc double %b, %c
- %1 = fsub reassoc double %a, %0
+ %0 = fmul reassoc nsz double %b, %c
+ %1 = fsub reassoc nsz double %a, %0
ret double %1
}
@@ -206,7 +218,7 @@ define double @test_fast_neg_fma_f64(double %a, double %b, double %c) {
; NO-VSX-NEXT: blr
entry:
%0 = fsub reassoc double -0.0, %a
- %1 = call reassoc double @llvm.fma.f64(double %0, double %b, double %c)
+ %1 = call reassoc nsz double @llvm.fma.f64(double %0, double %b, double %c)
ret double %1
}
@@ -222,7 +234,7 @@ define float @test_fast_mul_sub_f32(float %a, float %b, float %c) {
; NO-VSX-NEXT: blr
entry:
%0 = fmul reassoc float %b, %c
- %1 = fsub reassoc float %a, %0
+ %1 = fsub reassoc nsz float %a, %0
ret float %1
}
@@ -242,7 +254,7 @@ define float @test_fast_2mul_sub_f32(float %a, float %b, float %c, float %d) {
entry:
%0 = fmul reassoc float %a, %b
%1 = fmul reassoc float %c, %d
- %2 = fsub reassoc float %0, %1
+ %2 = fsub reassoc nsz float %0, %1
ret float %2
}
@@ -259,7 +271,7 @@ define float @test_fast_neg_fma_f32(float %a, float %b, float %c) {
; NO-VSX-NEXT: blr
entry:
%0 = fsub reassoc float -0.0, %a
- %1 = call reassoc float @llvm.fma.f32(float %0, float %b, float %c)
+ %1 = call reassoc nsz float @llvm.fma.f32(float %0, float %b, float %c)
ret float %1
}
@@ -278,7 +290,7 @@ define <2 x double> @test_fast_neg_fma_v2f64(<2 x double> %a, <2 x double> %b,
<2 x double> %c) {
entry:
%0 = fsub reassoc <2 x double> <double -0.0, double -0.0>, %a
- %1 = call reassoc <2 x double> @llvm.fma.v2f64(<2 x double> %0, <2 x double> %b,
+ %1 = call reassoc nsz <2 x double> @llvm.fma.v2f64(<2 x double> %0, <2 x double> %b,
<2 x double> %c)
ret <2 x double> %1
}
@@ -301,8 +313,8 @@ define <4 x float> @test_fast_neg_fma_v4f32(<4 x float> %a, <4 x float> %b,
entry:
%0 = fsub reassoc <4 x float> <float -0.0, float -0.0, float -0.0,
float -0.0>, %a
- %1 = call reassoc <4 x float> @llvm.fma.v4f32(<4 x float> %0, <4 x float> %b,
- <4 x float> %c)
+ %1 = call reassoc nsz <4 x float> @llvm.fma.v4f32(<4 x float> %0, <4 x float> %b,
+ <4 x float> %c)
ret <4 x float> %1
}
diff --git a/llvm/test/CodeGen/PowerPC/fma-precision.ll b/llvm/test/CodeGen/PowerPC/fma-precision.ll
index 8455e67e4fc5..0a8593193fa2 100644
--- a/llvm/test/CodeGen/PowerPC/fma-precision.ll
+++ b/llvm/test/CodeGen/PowerPC/fma-precision.ll
@@ -13,7 +13,7 @@ define double @fsub1(double %a, double %b, double %c, double %d) {
entry:
%mul = fmul reassoc double %b, %a
%mul1 = fmul reassoc double %d, %c
- %sub = fsub reassoc double %mul, %mul1
+ %sub = fsub reassoc nsz double %mul, %mul1
%mul3 = fmul reassoc double %mul, %sub
ret double %mul3
}
@@ -113,7 +113,7 @@ define double @fma_multi_uses1(double %a, double %b, double %c, double %d, doubl
store double %ab, double* %p1 ; extra use of %ab
store double %ab, double* %p2 ; another extra use of %ab
store double %cd, double* %p3 ; extra use of %cd
- %r = fsub reassoc double %ab, %cd
+ %r = fsub reassoc nsz double %ab, %cd
ret double %r
}
@@ -156,8 +156,8 @@ define double @fma_multi_uses3(double %a, double %b, double %c, double %d, doubl
store double %ab, double* %p1 ; extra use of %ab
store double %ab, double* %p2 ; another extra use of %ab
store double %fg, double* %p3 ; extra use of %fg
- %q = fsub reassoc double %fg, %cd ; The uses of %cd reduce to 1 after %r is folded. 2 uses of %fg, fold %cd, remove def of %cd
- %r = fsub reassoc double %ab, %cd ; Fold %r before %q. 3 uses of %ab, 2 uses of %cd, fold %cd
+ %q = fsub reassoc nsz double %fg, %cd ; The uses of %cd reduce to 1 after %r is folded. 2 uses of %fg, fold %cd, remove def of %cd
+ %r = fsub reassoc nsz double %ab, %cd ; Fold %r before %q. 3 uses of %ab, 2 uses of %cd, fold %cd
%add = fadd reassoc double %r, %q
ret double %add
}
diff --git a/llvm/test/CodeGen/PowerPC/fma.ll b/llvm/test/CodeGen/PowerPC/fma.ll
index 3f1b2102b8a5..b49b93b83b68 100644
--- a/llvm/test/CodeGen/PowerPC/fma.ll
+++ b/llvm/test/CodeGen/PowerPC/fma.ll
@@ -95,10 +95,25 @@ define double @test_FNMSUB1(double %A, double %B, double %C) {
%E = fsub double %C, %D ; <double> [#uses=1]
ret double %E
; CHECK-LABEL: test_FNMSUB1:
-; CHECK: fnmsub
+; CHECK: fneg
+; CHECK-NEXT: fmadd
; CHECK-NEXT: blr
; CHECK-VSX-LABEL: test_FNMSUB1:
+; CHECK-VSX: xsnegdp
+; CHECK-VSX-NEXT: xsmaddmdp
+}
+
+; need nsz flag to generate fnmsub since it may affect sign of zero
+define double @test_FNMSUB1_NSZ(double %A, double %B, double %C) {
+ %D = fmul nsz double %A, %B ; <double> [#uses=1]
+ %E = fsub nsz double %C, %D ; <double> [#uses=1]
+ ret double %E
+; CHECK-LABEL: test_FNMSUB1_NSZ:
+; CHECK: fnmsub
+; CHECK-NEXT: blr
+
+; CHECK-VSX-LABEL: test_FNMSUB1_NSZ:
; CHECK-VSX: xsnmsubmdp
}
diff --git a/llvm/test/CodeGen/PowerPC/recipest.ll b/llvm/test/CodeGen/PowerPC/recipest.ll
index f63f94166ec5..ebece0081a62 100644
--- a/llvm/test/CodeGen/PowerPC/recipest.ll
+++ b/llvm/test/CodeGen/PowerPC/recipest.ll
@@ -429,9 +429,9 @@ define float @rsqrt_fmul_fmf(float %a, float %b, float %c) {
; CHECK-P9-NEXT: xsmaddasp 4, 1, 0
; CHECK-P9-NEXT: xsmulsp 1, 3, 4
; CHECK-P9-NEXT: blr
- %x = call reassoc arcp float @llvm.sqrt.f32(float %a)
- %y = fmul reassoc float %x, %b
- %z = fdiv reassoc arcp float %c, %y
+ %x = call reassoc arcp nsz float @llvm.sqrt.f32(float %a)
+ %y = fmul reassoc nsz float %x, %b
+ %z = fdiv reassoc arcp nsz float %c, %y
ret float %z
}
@@ -651,7 +651,7 @@ define float @goo2_fmf(float %a, float %b) nounwind {
; CHECK-P9-NEXT: xsmaddasp 0, 3, 1
; CHECK-P9-NEXT: fmr 1, 0
; CHECK-P9-NEXT: blr
- %r = fdiv reassoc arcp float %a, %b
+ %r = fdiv reassoc arcp nsz float %a, %b
ret float %r
}
@@ -705,7 +705,7 @@ define <4 x float> @hoo2_fmf(<4 x float> %a, <4 x float> %b) nounwind {
; CHECK-P9-NEXT: xvmaddasp 0, 1, 34
; CHECK-P9-NEXT: xxlor 34, 0, 0
; CHECK-P9-NEXT: blr
- %r = fdiv reassoc arcp <4 x float> %a, %b
+ %r = fdiv reassoc arcp nsz <4 x float> %a, %b
ret <4 x float> %r
}
diff --git a/llvm/test/CodeGen/PowerPC/repeated-fp-divisors.ll b/llvm/test/CodeGen/PowerPC/repeated-fp-divisors.ll
index 3c7a9b94a891..0d9a67449bb7 100644
--- a/llvm/test/CodeGen/PowerPC/repeated-fp-divisors.ll
+++ b/llvm/test/CodeGen/PowerPC/repeated-fp-divisors.ll
@@ -13,9 +13,9 @@ define <4 x float> @repeated_fp_divisor(float %a, <4 x float> %b) {
; CHECK-NEXT: lvx 4, 0, 3
; CHECK-NEXT: xxspltw 0, 0, 0
; CHECK-NEXT: xvresp 1, 0
-; CHECK-NEXT: xvmaddasp 35, 0, 1
+; CHECK-NEXT: xvnmsubasp 35, 0, 1
; CHECK-NEXT: xvmulsp 0, 34, 36
-; CHECK-NEXT: xvnmsubasp 1, 1, 35
+; CHECK-NEXT: xvmaddasp 1, 1, 35
; CHECK-NEXT: xvmulsp 34, 0, 1
; CHECK-NEXT: blr
%ins = insertelement <4 x float> undef, float %a, i32 0
More information about the llvm-commits
mailing list