summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2020-01-10 10:31:25 -0800
committerCraig Topper <craig.topper@intel.com>2020-01-10 11:00:17 -0800
commitb590e0fd810e4caf59ab83b04654d42e18faaafb (patch)
tree9f65192876a6560c5725bee78348ff635a31fe95
parent13ec473b9d4bd4f7a558272932b7c0806171c666 (diff)
downloadbcm5719-llvm-b590e0fd810e4caf59ab83b04654d42e18faaafb.tar.gz
bcm5719-llvm-b590e0fd810e4caf59ab83b04654d42e18faaafb.zip
[TargetLowering][ARM][X86] Change softenSetCCOperands handling of ONE to avoid spurious exceptions for QNANs with strict FP quiet compares
ONE is currently softened to OGT | OLT. But the libcalls for OGT and OLT libcalls will trigger an exception for QNAN. At least for X86 with libgcc. UEQ on the other hand uses UO | OEQ. The UO and OEQ libcalls will not trigger an exception for QNAN. This patch changes ONE to use the inverse of the UEQ lowering. So we now produce O & UNE. Technically the existing behavior was correct for a signalling ONE, but since I don't know how to generate one of those from clang that seemed like something we can deal with later as we would need to fix other predicates as well. Also removing spurious exceptions seemed better than missing an exception. There are also problems with quiet OGT/OLT/OLE/OGE, but those are harder to fix. Differential Revision: https://reviews.llvm.org/D72477
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp19
-rw-r--r--llvm/test/CodeGen/Thumb2/float-cmp.ll12
-rw-r--r--llvm/test/CodeGen/X86/fp128-compare.ll10
-rw-r--r--llvm/test/CodeGen/X86/fp128-libcalls-strict.ll20
-rw-r--r--llvm/test/CodeGen/X86/fpcmp-soft-fp.ll10
5 files changed, 36 insertions, 35 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index a5ea7c121bd..20e794b6791 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -355,14 +355,9 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
(VT == MVT::f128) ? RTLIB::O_F128 : RTLIB::O_PPCF128;
break;
case ISD::SETONE:
- // SETONE = SETOLT | SETOGT
- LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 :
- (VT == MVT::f64) ? RTLIB::OLT_F64 :
- (VT == MVT::f128) ? RTLIB::OLT_F128 : RTLIB::OLT_PPCF128;
- LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 :
- (VT == MVT::f64) ? RTLIB::OGT_F64 :
- (VT == MVT::f128) ? RTLIB::OGT_F128 : RTLIB::OGT_PPCF128;
- break;
+ // SETONE = O && UNE
+ ShouldInvertCC = true;
+ LLVM_FALLTHROUGH;
case ISD::SETUEQ:
LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 :
(VT == MVT::f64) ? RTLIB::UO_F64 :
@@ -425,14 +420,18 @@ void TargetLowering::softenSetCCOperands(SelectionDAG &DAG, EVT VT,
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), RetVT),
NewLHS, NewRHS, DAG.getCondCode(CCCode));
auto Call2 = makeLibCall(DAG, LC2, RetVT, Ops, CallOptions, dl, Chain);
+ CCCode = getCmpLibcallCC(LC2);
+ if (ShouldInvertCC)
+ CCCode = getSetCCInverse(CCCode, RetVT);
NewLHS = DAG.getNode(
ISD::SETCC, dl,
getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), RetVT),
- Call2.first, NewRHS, DAG.getCondCode(getCmpLibcallCC(LC2)));
+ Call2.first, NewRHS, DAG.getCondCode(CCCode));
if (Chain)
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Call.second,
Call2.second);
- NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS);
+ NewLHS = DAG.getNode(ShouldInvertCC ? ISD::AND : ISD::OR, dl,
+ Tmp.getValueType(), Tmp, NewLHS);
NewRHS = SDValue();
}
}
diff --git a/llvm/test/CodeGen/Thumb2/float-cmp.ll b/llvm/test/CodeGen/Thumb2/float-cmp.ll
index ca9326ad66a..73e0063a927 100644
--- a/llvm/test/CodeGen/Thumb2/float-cmp.ll
+++ b/llvm/test/CodeGen/Thumb2/float-cmp.ll
@@ -54,8 +54,8 @@ define i1 @cmp_f_ole(float %a, float %b) {
}
define i1 @cmp_f_one(float %a, float %b) {
; CHECK-LABEL: cmp_f_one:
-; NONE: bl __aeabi_fcmpgt
-; NONE: bl __aeabi_fcmplt
+; NONE: bl __aeabi_fcmpeq
+; NONE: bl __aeabi_fcmpun
; HARD: vcmp.f32
; HARD: movmi r0, #1
; HARD: movgt r0, #1
@@ -198,10 +198,10 @@ define i1 @cmp_d_ole(double %a, double %b) {
}
define i1 @cmp_d_one(double %a, double %b) {
; CHECK-LABEL: cmp_d_one:
-; NONE: bl __aeabi_dcmpgt
-; NONE: bl __aeabi_dcmplt
-; SP: bl __aeabi_dcmpgt
-; SP: bl __aeabi_dcmplt
+; NONE: bl __aeabi_dcmpeq
+; NONE: bl __aeabi_dcmpun
+; SP: bl __aeabi_dcmpeq
+; SP: bl __aeabi_dcmpun
; DP: vcmp.f64
; DP: movmi r0, #1
; DP: movgt r0, #1
diff --git a/llvm/test/CodeGen/X86/fp128-compare.ll b/llvm/test/CodeGen/X86/fp128-compare.ll
index a642c5b477f..8aa4e554438 100644
--- a/llvm/test/CodeGen/X86/fp128-compare.ll
+++ b/llvm/test/CodeGen/X86/fp128-compare.ll
@@ -162,15 +162,15 @@ define i32 @TestComp128ONE(fp128 %d1, fp128 %d2) {
; CHECK-NEXT: .cfi_offset %rbx, -16
; CHECK-NEXT: movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
; CHECK-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
-; CHECK-NEXT: callq __gttf2
+; CHECK-NEXT: callq __eqtf2
; CHECK-NEXT: testl %eax, %eax
-; CHECK-NEXT: setg %bl
+; CHECK-NEXT: setne %bl
; CHECK-NEXT: movaps (%rsp), %xmm0 # 16-byte Reload
; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; CHECK-NEXT: callq __lttf2
+; CHECK-NEXT: callq __unordtf2
; CHECK-NEXT: testl %eax, %eax
-; CHECK-NEXT: sets %al
-; CHECK-NEXT: orb %bl, %al
+; CHECK-NEXT: sete %al
+; CHECK-NEXT: andb %bl, %al
; CHECK-NEXT: movzbl %al, %eax
; CHECK-NEXT: addq $32, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 16
diff --git a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
index 5b65b27896a..482ae36820a 100644
--- a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
+++ b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
@@ -1314,15 +1314,15 @@ define i64 @cmp_one_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
; CHECK-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill
; CHECK-NEXT: movq %rsi, %r14
; CHECK-NEXT: movq %rdi, %rbx
-; CHECK-NEXT: callq __gttf2
+; CHECK-NEXT: callq __eqtf2
; CHECK-NEXT: testl %eax, %eax
-; CHECK-NEXT: setg %bpl
+; CHECK-NEXT: setne %bpl
; CHECK-NEXT: movaps (%rsp), %xmm0 # 16-byte Reload
; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; CHECK-NEXT: callq __lttf2
+; CHECK-NEXT: callq __unordtf2
; CHECK-NEXT: testl %eax, %eax
-; CHECK-NEXT: sets %al
-; CHECK-NEXT: orb %bpl, %al
+; CHECK-NEXT: sete %al
+; CHECK-NEXT: testb %bpl, %al
; CHECK-NEXT: cmoveq %r14, %rbx
; CHECK-NEXT: movq %rbx, %rax
; CHECK-NEXT: addq $32, %rsp
@@ -1350,10 +1350,10 @@ define i64 @cmp_one_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
; X86-NEXT: pushl %edi
; X86-NEXT: pushl %ebp
; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: calll __gttf2
+; X86-NEXT: calll __eqtf2
; X86-NEXT: addl $32, %esp
; X86-NEXT: testl %eax, %eax
-; X86-NEXT: setg %bl
+; X86-NEXT: setne %bl
; X86-NEXT: pushl {{[0-9]+}}(%esp)
; X86-NEXT: pushl {{[0-9]+}}(%esp)
; X86-NEXT: pushl {{[0-9]+}}(%esp)
@@ -1362,11 +1362,11 @@ define i64 @cmp_one_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
; X86-NEXT: pushl %edi
; X86-NEXT: pushl %ebp
; X86-NEXT: pushl {{[0-9]+}}(%esp)
-; X86-NEXT: calll __lttf2
+; X86-NEXT: calll __unordtf2
; X86-NEXT: addl $32, %esp
; X86-NEXT: testl %eax, %eax
-; X86-NEXT: sets %al
-; X86-NEXT: orb %bl, %al
+; X86-NEXT: sete %al
+; X86-NEXT: testb %bl, %al
; X86-NEXT: leal {{[0-9]+}}(%esp), %eax
; X86-NEXT: leal {{[0-9]+}}(%esp), %ecx
; X86-NEXT: cmovnel %eax, %ecx
diff --git a/llvm/test/CodeGen/X86/fpcmp-soft-fp.ll b/llvm/test/CodeGen/X86/fpcmp-soft-fp.ll
index f96bf65e44b..e89acc6bb26 100644
--- a/llvm/test/CodeGen/X86/fpcmp-soft-fp.ll
+++ b/llvm/test/CodeGen/X86/fpcmp-soft-fp.ll
@@ -100,6 +100,7 @@ entry:
; CHECK: sete
; CHECK: calll __unorddf2
; CHECK: setne
+; CHECK: or
; CHECK: retl
define i1 @test11(double %d) #0 {
@@ -108,10 +109,11 @@ entry:
ret i1 %cmp
}
; CHECK-LABEL: test11:
-; CHECK: calll __gtdf2
-; CHECK: setg
-; CHECK: calll __ltdf2
-; CHECK: sets
+; CHECK: calll __eqdf2
+; CHECK: setne
+; CHECK: calll __unorddf2
+; CHECK: sete
+; CHECK: and
; CHECK: retl
define i1 @test12(double %d) #0 {
OpenPOWER on IntegriCloud