1; Verify that floating-point strict signaling compares cannot be omitted
2; even if CC already has the right value.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
5; RUN:   -enable-misched=0 -no-integrated-as | FileCheck %s
6;
7; We need -enable-misched=0 to make sure f12 and following routines really
8; test the compare elimination pass.
9
10
11declare float @llvm.fabs.f32(float %f)
12
13; Test addition followed by EQ, which could use the CC result of the addition.
14define float @f1(float %a, float %b, float *%dest) #0 {
15; CHECK-LABEL: f1:
16; CHECK-DAG: aebr %f0, %f2
17; CHECK-DAG: lzer [[REG:%f[0-9]+]]
18; CHECK-NEXT: kebr %f0, [[REG]]
19; CHECK-NEXT: ber %r14
20; CHECK: br %r14
21entry:
22  %res = call float @llvm.experimental.constrained.fadd.f32(
23                        float %a, float %b,
24                        metadata !"round.dynamic",
25                        metadata !"fpexcept.strict") #0
26  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(
27                                               float %res, float 0.0,
28                                               metadata !"oeq",
29                                               metadata !"fpexcept.strict") #0
30  br i1 %cmp, label %exit, label %store
31
32store:
33  store float %b, float *%dest
34  br label %exit
35
36exit:
37  ret float %res
38}
39
40; Test the result of LOAD POSITIVE.
41define float @f6(float %dummy, float %a, float *%dest) #0 {
42; CHECK-LABEL: f6:
43; CHECK-DAG: lpdfr %f0, %f2
44; CHECK-DAG: lzer [[REG:%f[0-9]+]]
45; CHECK-NEXT: kebr %f0, [[REG]]
46; CHECK-NEXT: bhr %r14
47; CHECK: br %r14
48entry:
49  %res = call float @llvm.fabs.f32(float %a)
50  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(
51                                               float %res, float 0.0,
52                                               metadata !"ogt",
53                                               metadata !"fpexcept.strict") #0
54  br i1 %cmp, label %exit, label %store
55
56store:
57  store float %res, float *%dest
58  br label %exit
59
60exit:
61  ret float %res
62}
63
64; Test the result of LOAD NEGATIVE.
65define float @f7(float %dummy, float %a, float *%dest) #0 {
66; CHECK-LABEL: f7:
67; CHECK-DAG: lndfr %f0, %f2
68; CHECK-DAG: lzer [[REG:%f[0-9]+]]
69; CHECK-NEXT: kebr %f0, [[REG]]
70; CHECK-NEXT: blr %r14
71; CHECK: br %r14
72entry:
73  %abs = call float @llvm.fabs.f32(float %a)
74  %res = fneg float %abs
75  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(
76                                               float %res, float 0.0,
77                                               metadata !"olt",
78                                               metadata !"fpexcept.strict") #0
79  br i1 %cmp, label %exit, label %store
80
81store:
82  store float %res, float *%dest
83  br label %exit
84
85exit:
86  ret float %res
87}
88
89; Test the result of LOAD COMPLEMENT.
90define float @f8(float %dummy, float %a, float *%dest) #0 {
91; CHECK-LABEL: f8:
92; CHECK-DAG: lcdfr %f0, %f2
93; CHECK-DAG: lzer [[REG:%f[0-9]+]]
94; CHECK-NEXT: kebr %f0, [[REG]]
95; CHECK-NEXT: bler %r14
96; CHECK: br %r14
97entry:
98  %res = fneg float %a
99  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(
100                                               float %res, float 0.0,
101                                               metadata !"ole",
102                                               metadata !"fpexcept.strict") #0
103  br i1 %cmp, label %exit, label %store
104
105store:
106  store float %res, float *%dest
107  br label %exit
108
109exit:
110  ret float %res
111}
112
113; Test that LER does not get converted to LTEBR.
114define float @f12(float %dummy, float %val) #0 {
115; CHECK-LABEL: f12:
116; CHECK: ler %f0, %f2
117; CHECK-NEXT: #APP
118; CHECK-NEXT: blah %f0
119; CHECK-NEXT: #NO_APP
120; CHECK-NEXT: lzer [[REG:%f[0-9]+]]
121; CHECK-NEXT: kebr %f2, [[REG]]
122; CHECK-NEXT: blr %r14
123; CHECK: br %r14
124entry:
125  %ret = call float asm "blah $1", "=f,{f0}"(float %val)
126  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(
127                                               float %val, float 0.0,
128                                               metadata !"olt",
129                                               metadata !"fpexcept.strict") #0
130  br i1 %cmp, label %exit, label %store
131
132store:
133  call void asm sideeffect "blah", ""()
134  br label %exit
135
136exit:
137  ret float %ret
138}
139
140attributes #0 = { strictfp }
141
142declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
143declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
144declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata)
145declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata)
146declare i1 @llvm.experimental.constrained.fcmps.f32(float, float, metadata, metadata)
147declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata)
148declare i1 @llvm.experimental.constrained.fcmps.f128(fp128, fp128, metadata, metadata)
149