From: Nemanja Ivanovic Date: Tue, 9 Oct 2018 23:20:11 +0000 (+0000) Subject: [DAGCombiner] Expand combining of FP logical ops to sign-setting FP ops X-Git-Tag: llvmorg-8.0.0-rc1~6933 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=72d4866e57666057e5d8c3e51065e9f895f37f29;p=platform%2Fupstream%2Fllvm.git [DAGCombiner] Expand combining of FP logical ops to sign-setting FP ops We already do the following combines: (bitcast int (and (bitcast fp X to int), 0x7fff...) to fp) -> fabs X (bitcast int (xor (bitcast fp X to int), 0x8000...) to fp) -> fneg X When the target has "bit preserving fp logic". This patch just extends it to also combine: (bitcast int (or (bitcast fp X to int), 0x8000...) to fp) -> fneg (fabs X) As some targets have fnabs and even those that don't can efficiently lower both the fabs and the fneg. Differential revision: https://reviews.llvm.org/D44548 llvm-svn: 344093 --- diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9c70b66..29adcad 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -83,6 +83,7 @@ STATISTIC(PostIndexedNodes, "Number of post-indexed nodes created"); STATISTIC(OpsNarrowed , "Number of load/op/store narrowed"); STATISTIC(LdStFP2Int , "Number of fp load/store pairs transformed to int"); STATISTIC(SlicedLoads, "Number of load sliced"); +STATISTIC(NumFPLogicOpsConv, "Number of logic ops converted to fp ops"); static cl::opt CombinerGlobalAA("combiner-global-alias-analysis", cl::Hidden, @@ -9843,19 +9844,29 @@ static SDValue foldBitcastedFPLogic(SDNode *N, SelectionDAG &DAG, FPOpcode = ISD::FNEG; SignMask = APInt::getSignMask(SourceVT.getScalarSizeInBits()); break; - // TODO: ISD::OR --> ISD::FNABS? + case ISD::OR: + FPOpcode = ISD::FABS; + SignMask = APInt::getSignMask(SourceVT.getScalarSizeInBits()); + break; default: return SDValue(); } // Fold (bitcast int (and (bitcast fp X to int), 0x7fff...) to fp) -> fabs X // Fold (bitcast int (xor (bitcast fp X to int), 0x8000...) to fp) -> fneg X + // Fold (bitcast int (or (bitcast fp X to int), 0x8000...) to fp) -> + // fneg (fabs X) SDValue LogicOp0 = N0.getOperand(0); ConstantSDNode *LogicOp1 = isConstOrConstSplat(N0.getOperand(1), true); if (LogicOp1 && LogicOp1->getAPIntValue() == SignMask && LogicOp0.getOpcode() == ISD::BITCAST && - LogicOp0.getOperand(0).getValueType() == VT) - return DAG.getNode(FPOpcode, SDLoc(N), VT, LogicOp0.getOperand(0)); + LogicOp0.getOperand(0).getValueType() == VT) { + SDValue FPOp = DAG.getNode(FPOpcode, SDLoc(N), VT, LogicOp0.getOperand(0)); + NumFPLogicOpsConv++; + if (N0.getOpcode() == ISD::OR) + return DAG.getNode(ISD::FNEG, SDLoc(N), VT, FPOp); + return FPOp; + } return SDValue(); } diff --git a/llvm/test/CodeGen/AArch64/fabs.ll b/llvm/test/CodeGen/AArch64/fabs.ll index fa982d1..cd315ab 100644 --- a/llvm/test/CodeGen/AArch64/fabs.ll +++ b/llvm/test/CodeGen/AArch64/fabs.ll @@ -37,9 +37,8 @@ define float @still_not_fabs(float %x) #0 { define float @nabsf(float %a) { ; CHECK-LABEL: nabsf: ; CHECK: // %bb.0: -; CHECK-NEXT: fmov w8, s0 -; CHECK-NEXT: orr w8, w8, #0x80000000 -; CHECK-NEXT: fmov s0, w8 +; CHECK-NEXT: fabs s0, s0 +; CHECK-NEXT: fneg s0, s0 ; CHECK-NEXT: ret %conv = bitcast float %a to i32 %and = or i32 %conv, -2147483648 @@ -50,9 +49,8 @@ define float @nabsf(float %a) { define double @nabsd(double %a) { ; CHECK-LABEL: nabsd: ; CHECK: // %bb.0: -; CHECK-NEXT: fmov x8, d0 -; CHECK-NEXT: orr x8, x8, #0x8000000000000000 -; CHECK-NEXT: fmov d0, x8 +; CHECK-NEXT: fabs d0, d0 +; CHECK-NEXT: fneg d0, d0 ; CHECK-NEXT: ret %conv = bitcast double %a to i64 %and = or i64 %conv, -9223372036854775808 diff --git a/llvm/test/CodeGen/PowerPC/float-logic-ops.ll b/llvm/test/CodeGen/PowerPC/float-logic-ops.ll index 59660d4..5bef4fa 100644 --- a/llvm/test/CodeGen/PowerPC/float-logic-ops.ll +++ b/llvm/test/CodeGen/PowerPC/float-logic-ops.ll @@ -127,13 +127,7 @@ entry: define float @nabsf(float %a) { ; CHECK-LABEL: nabsf: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: xscvdpspn vs0, f1 -; CHECK-NEXT: xxsldwi vs0, vs0, vs0, 3 -; CHECK-NEXT: mfvsrwz r3, f0 -; CHECK-NEXT: oris r3, r3, 32768 -; CHECK-NEXT: mtvsrd f0, r3 -; CHECK-NEXT: xxsldwi vs0, vs0, vs0, 1 -; CHECK-NEXT: xscvspdpn f1, vs0 +; CHECK-NEXT: fnabs f1, f1 ; CHECK-NEXT: blr entry: %conv = bitcast float %a to i32 @@ -145,11 +139,7 @@ entry: define double @nabsd(double %a) { ; CHECK-LABEL: nabsd: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: li r3, 1 -; CHECK-NEXT: mffprd r4, f1 -; CHECK-NEXT: sldi r3, r3, 63 -; CHECK-NEXT: or r3, r4, r3 -; CHECK-NEXT: mtvsrd f1, r3 +; CHECK-NEXT: xsnabsdp f1, f1 ; CHECK-NEXT: blr entry: %conv = bitcast double %a to i64 @@ -161,9 +151,7 @@ entry: define <4 x float> @nabsv4f32(<4 x float> %a) { ; CHECK-LABEL: nabsv4f32: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: vspltisb v3, -1 -; CHECK-NEXT: vslw v3, v3, v3 -; CHECK-NEXT: xxlor vs34, vs34, vs35 +; CHECK-NEXT: xvnabssp vs34, vs34 ; CHECK-NEXT: blr entry: %conv = bitcast <4 x float> %a to <4 x i32> @@ -175,11 +163,7 @@ entry: define <2 x double> @nabsv2d64(<2 x double> %a) { ; CHECK-LABEL: nabsv2d64: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: addis r3, r2, .LCPI13_0@toc@ha -; CHECK-NEXT: addi r3, r3, .LCPI13_0@toc@l -; CHECK-NEXT: lxvd2x vs0, 0, r3 -; CHECK-NEXT: xxswapd vs35, vs0 -; CHECK-NEXT: xxlor vs34, vs34, vs35 +; CHECK-NEXT: xvnabsdp vs34, vs34 ; CHECK-NEXT: blr entry: %conv = bitcast <2 x double> %a to <2 x i64> diff --git a/llvm/test/CodeGen/X86/fp-logic.ll b/llvm/test/CodeGen/X86/fp-logic.ll index 71e40a4..59a77a6 100644 --- a/llvm/test/CodeGen/X86/fp-logic.ll +++ b/llvm/test/CodeGen/X86/fp-logic.ll @@ -311,8 +311,7 @@ define float @fsub_bitcast_fneg(float %x, float %y) { define float @nabsf(float %a) { ; CHECK-LABEL: nabsf: ; CHECK: # %bb.0: -; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero -; CHECK-NEXT: orps %xmm1, %xmm0 +; CHECK-NEXT: orps {{.*}}(%rip), %xmm0 ; CHECK-NEXT: retq %conv = bitcast float %a to i32 %and = or i32 %conv, -2147483648 @@ -323,8 +322,7 @@ define float @nabsf(float %a) { define double @nabsd(double %a) { ; CHECK-LABEL: nabsd: ; CHECK: # %bb.0: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero -; CHECK-NEXT: orps %xmm1, %xmm0 +; CHECK-NEXT: orps {{.*}}(%rip), %xmm0 ; CHECK-NEXT: retq %conv = bitcast double %a to i64 %and = or i64 %conv, -9223372036854775808