1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00
llvm-mirror/test/CodeGen/SystemZ/vec-strict-cmp-03.ll
Ulrich Weigand b5b6e8e953 [FPEnv] Constrained FCmp intrinsics
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
2019-12-07 11:28:39 +01:00

443 lines
18 KiB
LLVM

; Test strict f32 and v4f32 comparisons on z14.
;
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
; Test oeq.
define <4 x i32> @f1(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f1:
; CHECK: vfcesb %v24, %v26, %v28
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.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 one.
define <4 x i32> @f2(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f2:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v26, %v28
; CHECK: vo %v24, [[REG1]], [[REG2]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"one",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ogt.
define <4 x i32> @f3(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f3:
; CHECK: vfchsb %v24, %v26, %v28
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ogt",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test oge.
define <4 x i32> @f4(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f4:
; CHECK: vfchesb %v24, %v26, %v28
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"oge",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ole.
define <4 x i32> @f5(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f5:
; CHECK: vfchesb %v24, %v28, %v26
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ole",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test olt.
define <4 x i32> @f6(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f6:
; CHECK: vfchsb %v24, %v28, %v26
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"olt",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ueq.
define <4 x i32> @f7(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f7:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v26, %v28
; CHECK: vno %v24, [[REG1]], [[REG2]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ueq",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test une.
define <4 x i32> @f8(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f8:
; CHECK: vfcesb [[REG:%v[0-9]+]], %v26, %v28
; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"une",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ugt.
define <4 x i32> @f9(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
; CHECK-LABEL: f9:
; CHECK: vfchesb [[REG:%v[0-9]+]], %v28, %v26
; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ugt",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test uge.
define <4 x i32> @f10(<4 x i32> %dummy, <4 x float> %val1,
<4 x float> %val2) #0 {
; CHECK-LABEL: f10:
; CHECK: vfchsb [[REG:%v[0-9]+]], %v28, %v26
; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"uge",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ule.
define <4 x i32> @f11(<4 x i32> %dummy, <4 x float> %val1,
<4 x float> %val2) #0 {
; CHECK-LABEL: f11:
; CHECK: vfchsb [[REG:%v[0-9]+]], %v26, %v28
; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ule",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ult.
define <4 x i32> @f12(<4 x i32> %dummy, <4 x float> %val1,
<4 x float> %val2) #0 {
; CHECK-LABEL: f12:
; CHECK: vfchesb [[REG:%v[0-9]+]], %v26, %v28
; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ult",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test ord.
define <4 x i32> @f13(<4 x i32> %dummy, <4 x float> %val1,
<4 x float> %val2) #0 {
; CHECK-LABEL: f13:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v26, %v28
; CHECK: vo %v24, [[REG1]], [[REG2]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ord",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test uno.
define <4 x i32> @f14(<4 x i32> %dummy, <4 x float> %val1,
<4 x float> %val2) #0 {
; CHECK-LABEL: f14:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v26, %v28
; CHECK: vno %v24, [[REG1]], [[REG2]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"uno",
metadata !"fpexcept.strict") #0
%ret = sext <4 x i1> %cmp to <4 x i32>
ret <4 x i32> %ret
}
; Test oeq selects.
define <4 x float> @f15(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f15:
; CHECK: vfcesb [[REG:%v[0-9]+]], %v24, %v26
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"oeq",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test one selects.
define <4 x float> @f16(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f16:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v24, %v26
; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"one",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ogt selects.
define <4 x float> @f17(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f17:
; CHECK: vfchsb [[REG:%v[0-9]+]], %v24, %v26
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ogt",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test oge selects.
define <4 x float> @f18(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f18:
; CHECK: vfchesb [[REG:%v[0-9]+]], %v24, %v26
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"oge",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ole selects.
define <4 x float> @f19(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f19:
; CHECK: vfchesb [[REG:%v[0-9]+]], %v26, %v24
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ole",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test olt selects.
define <4 x float> @f20(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f20:
; CHECK: vfchsb [[REG:%v[0-9]+]], %v26, %v24
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"olt",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ueq selects.
define <4 x float> @f21(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f21:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v24, %v26
; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ueq",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test une selects.
define <4 x float> @f22(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f22:
; CHECK: vfcesb [[REG:%v[0-9]+]], %v24, %v26
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"une",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ugt selects.
define <4 x float> @f23(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f23:
; CHECK: vfchesb [[REG:%v[0-9]+]], %v26, %v24
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ugt",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test uge selects.
define <4 x float> @f24(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f24:
; CHECK: vfchsb [[REG:%v[0-9]+]], %v26, %v24
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"uge",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ule selects.
define <4 x float> @f25(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f25:
; CHECK: vfchsb [[REG:%v[0-9]+]], %v24, %v26
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ule",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ult selects.
define <4 x float> @f26(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f26:
; CHECK: vfchesb [[REG:%v[0-9]+]], %v24, %v26
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ult",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test ord selects.
define <4 x float> @f27(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f27:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v24, %v26
; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"ord",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test uno selects.
define <4 x float> @f28(<4 x float> %val1, <4 x float> %val2,
<4 x float> %val3, <4 x float> %val4) #0 {
; CHECK-LABEL: f28:
; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v24, %v26
; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
; CHECK-NEXT: br %r14
%cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
<4 x float> %val1, <4 x float> %val2,
metadata !"uno",
metadata !"fpexcept.strict") #0
%ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
ret <4 x float> %ret
}
; Test an f32 comparison that uses vector registers.
define i64 @f29(i64 %a, i64 %b, float %f1, <4 x float> %vec) #0 {
; CHECK-LABEL: f29:
; CHECK: wfcsb %f0, %v24
; CHECK-NEXT: locgrne %r2, %r3
; CHECK: br %r14
%f2 = extractelement <4 x float> %vec, i32 0
%cond = call i1 @llvm.experimental.constrained.fcmp.f32(
float %f1, float %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.fcmp.v4f32(<4 x float>, <4 x float>, metadata, metadata)
declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata)