mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
b5b6e8e953
This adds support for constrained floating-point comparison intrinsics. Specifically, we add: declare <ty2> @llvm.experimental.constrained.fcmp(<type> <op1>, <type> <op2>, metadata <condition code>, metadata <exception behavior>) declare <ty2> @llvm.experimental.constrained.fcmps(<type> <op1>, <type> <op2>, metadata <condition code>, metadata <exception behavior>) The first variant implements an IEEE "quiet" comparison (i.e. we only get an invalid FP exception if either argument is a SNaN), while the second variant implements an IEEE "signaling" comparison (i.e. we get an invalid FP exception if either argument is any NaN). The condition code is implemented as a metadata string. The same set of predicates as for the fcmp instruction is supported (except for the "true" and "false" predicates). These new intrinsics are mapped by SelectionDAG codegen onto two new ISD opcodes, ISD::STRICT_FSETCC and ISD::STRICT_FSETCCS, again representing quiet vs. signaling comparison operations. Otherwise those nodes look like SETCC nodes, with an additional chain argument and result as usual for strict FP nodes. The patch includes support for the common legalization operations for those nodes. The patch also includes full SystemZ back-end support for the new ISD nodes, mapping them to all available SystemZ instruction to fully implement strict semantics (scalar and vector). Differential Revision: https://reviews.llvm.org/D69281
57 lines
2.2 KiB
LLVM
57 lines
2.2 KiB
LLVM
; Test signaling vector floating-point comparisons on z13.
|
|
; Note that these must be scalarized as we do not have native instructions.
|
|
;
|
|
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
|
|
|
|
; Test v4f32.
|
|
define <4 x i32> @f1(<4 x float> %val1, <4 x float> %val2) #0 {
|
|
; CHECK-LABEL: f1:
|
|
; CHECK: kebr
|
|
; CHECK: kebr
|
|
; CHECK: kebr
|
|
; CHECK: kebr
|
|
; CHECK: br %r14
|
|
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmps.v4f32(
|
|
<4 x float> %val1, <4 x float> %val2,
|
|
metadata !"oeq",
|
|
metadata !"fpexcept.strict") #0
|
|
%ret = sext <4 x i1> %cmp to <4 x i32>
|
|
ret <4 x i32> %ret
|
|
}
|
|
|
|
; Test v2f64.
|
|
define <2 x i64> @f2(<2 x i64> %dummy, <2 x double> %val1, <2 x double> %val2) #0 {
|
|
; CHECK-LABEL: f2:
|
|
; CHECK: {{kdbr|wfkdb}}
|
|
; CHECK: {{kdbr|wfkdb}}
|
|
; CHECK: br %r14
|
|
%cmp = call <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(
|
|
<2 x double> %val1, <2 x double> %val2,
|
|
metadata !"oeq",
|
|
metadata !"fpexcept.strict") #0
|
|
%ret = sext <2 x i1> %cmp to <2 x i64>
|
|
ret <2 x i64> %ret
|
|
}
|
|
|
|
; Test an f64 comparison that uses vector registers.
|
|
define i64 @f3(i64 %a, i64 %b, double %f1, <2 x double> %vec) #0 {
|
|
; CHECK-LABEL: f3:
|
|
; CHECK: wfkdb %f0, %v24
|
|
; CHECK-NEXT: locgrne %r2, %r3
|
|
; CHECK: br %r14
|
|
%f2 = extractelement <2 x double> %vec, i32 0
|
|
%cond = call i1 @llvm.experimental.constrained.fcmps.f64(
|
|
double %f1, double %f2,
|
|
metadata !"oeq",
|
|
metadata !"fpexcept.strict") #0
|
|
%res = select i1 %cond, i64 %a, i64 %b
|
|
ret i64 %res
|
|
}
|
|
|
|
attributes #0 = { strictfp }
|
|
|
|
declare <4 x i1> @llvm.experimental.constrained.fcmps.v4f32(<4 x float>, <4 x float>, metadata, metadata)
|
|
declare <2 x i1> @llvm.experimental.constrained.fcmps.v2f64(<2 x double>, <2 x double>, metadata, metadata)
|
|
declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata)
|
|
|