[llvm] 4a54e3e - [x86] try to replace 0.0 in fcmp with negated operand
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 31 06:17:55 PDT 2022
Author: Sanjay Patel
Date: 2022-03-31T09:17:49-04:00
New Revision: 4a54e3eed347ca2bcb840c52c553892101afd252
URL: https://github.com/llvm/llvm-project/commit/4a54e3eed347ca2bcb840c52c553892101afd252
DIFF: https://github.com/llvm/llvm-project/commit/4a54e3eed347ca2bcb840c52c553892101afd252.diff
LOG: [x86] try to replace 0.0 in fcmp with negated operand
This inverts a fold recently added to IR with:
3491f2f4b033
We can put -bidirectional on the Alive2 examples to show that
the reverse transforms work:
https://alive2.llvm.org/ce/z/8iVQwB
The motivation for the IR change was to improve matching to
'fabs' in IR (see https://github.com/llvm/llvm-project/issues/38828 ),
but it regressed x86 codegen for 'not-quite-fabs' patterns like
(X > -X) ? X : -X.
Ie, when there is no fast-math (nsz), the cmp+select is not a proper
fabs operation, but it does map nicely to the unusual NAN semantics
of MINSS/MAXSS.
I drafted this as a target-independent fold, but it doesn't appear to
help any other targets and seems to cause regressions for SystemZ at
least.
Differential Revision: https://reviews.llvm.org/D122726
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/fp-stack-compare.ll
llvm/test/CodeGen/X86/setcc-combine.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8521b0e36f3af..80fec0a54ef69 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -51502,6 +51502,16 @@ static SDValue combineSetCC(SDNode *N, SelectionDAG &DAG,
LHS.getValueType() == MVT::v4f32)
return LowerVSETCC(SDValue(N, 0), Subtarget, DAG);
+ // X pred 0.0 --> X pred -X
+ // If the negation of X already exists, use it in the comparison. This removes
+ // the need to materialize 0.0 and allows matching to SSE's MIN/MAX
+ // instructions in patterns with a 'select' node.
+ if (isNullFPScalarOrVectorConst(RHS)) {
+ SDVTList FNegVT = DAG.getVTList(OpVT);
+ if (SDNode *FNeg = DAG.getNodeIfExists(ISD::FNEG, FNegVT, {LHS}))
+ return DAG.getSetCC(DL, VT, LHS, SDValue(FNeg, 0), CC);
+ }
+
return SDValue();
}
diff --git a/llvm/test/CodeGen/X86/fp-stack-compare.ll b/llvm/test/CodeGen/X86/fp-stack-compare.ll
index 83796b39e4b85..fabcbafb07378 100644
--- a/llvm/test/CodeGen/X86/fp-stack-compare.ll
+++ b/llvm/test/CodeGen/X86/fp-stack-compare.ll
@@ -8,13 +8,12 @@ define float @foo(float* %col) {
; BASE: # %bb.0:
; BASE-NEXT: movl {{[0-9]+}}(%esp), %eax
; BASE-NEXT: flds (%eax)
-; BASE-NEXT: fldz
-; BASE-NEXT: fucomp %st(1)
+; BASE-NEXT: fld %st(0)
+; BASE-NEXT: fchs
+; BASE-NEXT: fucom %st(1)
; BASE-NEXT: fnstsw %ax
; BASE-NEXT: # kill: def $ah killed $ah killed $ax
; BASE-NEXT: sahf
-; BASE-NEXT: fld %st(0)
-; BASE-NEXT: fchs
; BASE-NEXT: ja .LBB0_2
; BASE-NEXT: # %bb.1:
; BASE-NEXT: fstp %st(0)
@@ -28,10 +27,9 @@ define float @foo(float* %col) {
; CMOV: # %bb.0:
; CMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
; CMOV-NEXT: flds (%eax)
-; CMOV-NEXT: fldz
-; CMOV-NEXT: fucompi %st(1), %st
; CMOV-NEXT: fld %st(0)
; CMOV-NEXT: fchs
+; CMOV-NEXT: fucomi %st(1), %st
; CMOV-NEXT: fxch %st(1)
; CMOV-NEXT: fcmovnbe %st(1), %st
; CMOV-NEXT: fstp %st(1)
diff --git a/llvm/test/CodeGen/X86/setcc-combine.ll b/llvm/test/CodeGen/X86/setcc-combine.ll
index 33d58ca018f0f..44994ab07ea6b 100644
--- a/llvm/test/CodeGen/X86/setcc-combine.ll
+++ b/llvm/test/CodeGen/X86/setcc-combine.ll
@@ -364,12 +364,7 @@ define float @olt(float %x) {
; CHECK: # %bb.0:
; CHECK-NEXT: movaps {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorps %xmm0, %xmm1
-; CHECK-NEXT: xorps %xmm2, %xmm2
-; CHECK-NEXT: movaps %xmm0, %xmm3
-; CHECK-NEXT: cmpltss %xmm2, %xmm3
-; CHECK-NEXT: andps %xmm3, %xmm0
-; CHECK-NEXT: andnps %xmm1, %xmm3
-; CHECK-NEXT: orps %xmm3, %xmm0
+; CHECK-NEXT: minss %xmm1, %xmm0
; CHECK-NEXT: retq
%cmp = fcmp olt float %x, 0.0
%neg = fneg float %x
@@ -382,11 +377,7 @@ define double @ogt(double %x) {
; CHECK: # %bb.0:
; CHECK-NEXT: movapd {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0]
; CHECK-NEXT: xorpd %xmm0, %xmm1
-; CHECK-NEXT: xorpd %xmm2, %xmm2
-; CHECK-NEXT: cmpltsd %xmm0, %xmm2
-; CHECK-NEXT: andpd %xmm2, %xmm0
-; CHECK-NEXT: andnpd %xmm1, %xmm2
-; CHECK-NEXT: orpd %xmm2, %xmm0
+; CHECK-NEXT: maxsd %xmm1, %xmm0
; CHECK-NEXT: retq
%neg = fneg double %x
%cmp = fcmp ogt double %x, 0.0
@@ -395,28 +386,13 @@ define double @ogt(double %x) {
}
define <4 x float> @olt_swap(<4 x float> %x) {
-; SSE2-LABEL: olt_swap:
-; SSE2: # %bb.0:
-; SSE2-NEXT: xorps %xmm1, %xmm1
-; SSE2-NEXT: movaps %xmm0, %xmm2
-; SSE2-NEXT: cmpltps %xmm1, %xmm2
-; SSE2-NEXT: movaps %xmm2, %xmm1
-; SSE2-NEXT: andnps %xmm0, %xmm1
-; SSE2-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT: andps %xmm2, %xmm0
-; SSE2-NEXT: orps %xmm1, %xmm0
-; SSE2-NEXT: retq
-;
-; SSE41-LABEL: olt_swap:
-; SSE41: # %bb.0:
-; SSE41-NEXT: movaps %xmm0, %xmm1
-; SSE41-NEXT: xorps %xmm2, %xmm2
-; SSE41-NEXT: cmpltps %xmm2, %xmm0
-; SSE41-NEXT: movaps {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
-; SSE41-NEXT: xorps %xmm1, %xmm2
-; SSE41-NEXT: blendvps %xmm0, %xmm2, %xmm1
-; SSE41-NEXT: movaps %xmm1, %xmm0
-; SSE41-NEXT: retq
+; CHECK-LABEL: olt_swap:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movaps {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
+; CHECK-NEXT: xorps %xmm0, %xmm1
+; CHECK-NEXT: maxps %xmm0, %xmm1
+; CHECK-NEXT: movaps %xmm1, %xmm0
+; CHECK-NEXT: retq
%cmp = fcmp olt <4 x float> %x, zeroinitializer
%neg = fneg <4 x float> %x
%r = select <4 x i1> %cmp, <4 x float> %neg, <4 x float> %x
@@ -424,28 +400,13 @@ define <4 x float> @olt_swap(<4 x float> %x) {
}
define <2 x double> @ogt_swap(<2 x double> %x) {
-; SSE2-LABEL: ogt_swap:
-; SSE2: # %bb.0:
-; SSE2-NEXT: movapd {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0]
-; SSE2-NEXT: xorpd %xmm0, %xmm2
-; SSE2-NEXT: xorpd %xmm1, %xmm1
-; SSE2-NEXT: cmpltpd %xmm0, %xmm1
-; SSE2-NEXT: andpd %xmm1, %xmm2
-; SSE2-NEXT: andnpd %xmm0, %xmm1
-; SSE2-NEXT: orpd %xmm2, %xmm1
-; SSE2-NEXT: movapd %xmm1, %xmm0
-; SSE2-NEXT: retq
-;
-; SSE41-LABEL: ogt_swap:
-; SSE41: # %bb.0:
-; SSE41-NEXT: movapd %xmm0, %xmm1
-; SSE41-NEXT: movapd {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0]
-; SSE41-NEXT: xorpd %xmm0, %xmm2
-; SSE41-NEXT: xorpd %xmm0, %xmm0
-; SSE41-NEXT: cmpltpd %xmm1, %xmm0
-; SSE41-NEXT: blendvpd %xmm0, %xmm2, %xmm1
-; SSE41-NEXT: movapd %xmm1, %xmm0
-; SSE41-NEXT: retq
+; CHECK-LABEL: ogt_swap:
+; CHECK: # %bb.0:
+; CHECK-NEXT: movapd {{.*#+}} xmm1 = [-0.0E+0,-0.0E+0]
+; CHECK-NEXT: xorpd %xmm0, %xmm1
+; CHECK-NEXT: minpd %xmm0, %xmm1
+; CHECK-NEXT: movapd %xmm1, %xmm0
+; CHECK-NEXT: retq
%neg = fneg <2 x double> %x
%cmp = fcmp ogt <2 x double> %x, zeroinitializer
%r = select <2 x i1> %cmp, <2 x double> %neg, <2 x double> %x
@@ -455,23 +416,22 @@ define <2 x double> @ogt_swap(<2 x double> %x) {
define <4 x float> @ole(<4 x float> %x) {
; SSE2-LABEL: ole:
; SSE2: # %bb.0:
-; SSE2-NEXT: xorps %xmm1, %xmm1
-; SSE2-NEXT: movaps %xmm0, %xmm2
-; SSE2-NEXT: cmpleps %xmm1, %xmm2
-; SSE2-NEXT: movaps %xmm2, %xmm1
+; SSE2-NEXT: movaps {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
+; SSE2-NEXT: xorps %xmm0, %xmm2
+; SSE2-NEXT: movaps %xmm0, %xmm1
+; SSE2-NEXT: cmpleps %xmm2, %xmm1
+; SSE2-NEXT: andps %xmm1, %xmm2
; SSE2-NEXT: andnps %xmm0, %xmm1
-; SSE2-NEXT: xorps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT: andps %xmm2, %xmm0
-; SSE2-NEXT: orps %xmm1, %xmm0
+; SSE2-NEXT: orps %xmm2, %xmm1
+; SSE2-NEXT: movaps %xmm1, %xmm0
; SSE2-NEXT: retq
;
; SSE41-LABEL: ole:
; SSE41: # %bb.0:
; SSE41-NEXT: movaps %xmm0, %xmm1
-; SSE41-NEXT: xorps %xmm2, %xmm2
-; SSE41-NEXT: cmpleps %xmm2, %xmm0
; SSE41-NEXT: movaps {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0,-0.0E+0,-0.0E+0]
-; SSE41-NEXT: xorps %xmm1, %xmm2
+; SSE41-NEXT: xorps %xmm0, %xmm2
+; SSE41-NEXT: cmpleps %xmm2, %xmm0
; SSE41-NEXT: blendvps %xmm0, %xmm2, %xmm1
; SSE41-NEXT: movaps %xmm1, %xmm0
; SSE41-NEXT: retq
@@ -486,7 +446,7 @@ define <2 x double> @oge(<2 x double> %x) {
; SSE2: # %bb.0:
; SSE2-NEXT: movapd {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0]
; SSE2-NEXT: xorpd %xmm0, %xmm2
-; SSE2-NEXT: xorpd %xmm1, %xmm1
+; SSE2-NEXT: movapd %xmm2, %xmm1
; SSE2-NEXT: cmplepd %xmm0, %xmm1
; SSE2-NEXT: andpd %xmm1, %xmm2
; SSE2-NEXT: andnpd %xmm0, %xmm1
@@ -499,7 +459,7 @@ define <2 x double> @oge(<2 x double> %x) {
; SSE41-NEXT: movapd %xmm0, %xmm1
; SSE41-NEXT: movapd {{.*#+}} xmm2 = [-0.0E+0,-0.0E+0]
; SSE41-NEXT: xorpd %xmm0, %xmm2
-; SSE41-NEXT: xorpd %xmm0, %xmm0
+; SSE41-NEXT: movapd %xmm2, %xmm0
; SSE41-NEXT: cmplepd %xmm1, %xmm0
; SSE41-NEXT: blendvpd %xmm0, %xmm2, %xmm1
; SSE41-NEXT: movapd %xmm1, %xmm0
@@ -510,6 +470,8 @@ define <2 x double> @oge(<2 x double> %x) {
ret <2 x double> %r
}
+; negative test - don't create an fneg to replace 0.0 operand
+
define double @ogt_no_fneg(double %x, double %y) {
; CHECK-LABEL: ogt_no_fneg:
; CHECK: # %bb.0:
@@ -524,6 +486,8 @@ define double @ogt_no_fneg(double %x, double %y) {
ret double %r
}
+; negative test - can't change the setcc for non-zero constant
+
define double @ogt_no_zero(double %x) {
; CHECK-LABEL: ogt_no_zero:
; CHECK: # %bb.0:
More information about the llvm-commits
mailing list