1 ; Test that floating-point compares are ommitted if CC already has the 2 ; right value. 3 ; 4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 5 6 declare float @llvm.fabs.f32(float %f) 7 8 ; Test addition followed by EQ, which can use the CC result of the addition. 9 define float @f1(float %a, float %b, float *%dest) { 10 ; CHECK-LABEL: f1: 11 ; CHECK: aebr %f0, %f2 12 ; CHECK-NEXT: je .L{{.*}} 13 ; CHECK: br %r14 14 entry: 15 %res = fadd float %a, %b 16 %cmp = fcmp oeq float %res, 0.0 17 br i1 %cmp, label %exit, label %store 18 19 store: 20 store float %b, float *%dest 21 br label %exit 22 23 exit: 24 ret float %res 25 } 26 27 ; ...and again with LT. 28 define float @f2(float %a, float %b, float *%dest) { 29 ; CHECK-LABEL: f2: 30 ; CHECK: aebr %f0, %f2 31 ; CHECK-NEXT: jl .L{{.*}} 32 ; CHECK: br %r14 33 entry: 34 %res = fadd float %a, %b 35 %cmp = fcmp olt float %res, 0.0 36 br i1 %cmp, label %exit, label %store 37 38 store: 39 store float %b, float *%dest 40 br label %exit 41 42 exit: 43 ret float %res 44 } 45 46 ; ...and again with GT. 47 define float @f3(float %a, float %b, float *%dest) { 48 ; CHECK-LABEL: f3: 49 ; CHECK: aebr %f0, %f2 50 ; CHECK-NEXT: jh .L{{.*}} 51 ; CHECK: br %r14 52 entry: 53 %res = fadd float %a, %b 54 %cmp = fcmp ogt float %res, 0.0 55 br i1 %cmp, label %exit, label %store 56 57 store: 58 store float %b, float *%dest 59 br label %exit 60 61 exit: 62 ret float %res 63 } 64 65 ; ...and again with UEQ. 66 define float @f4(float %a, float %b, float *%dest) { 67 ; CHECK-LABEL: f4: 68 ; CHECK: aebr %f0, %f2 69 ; CHECK-NEXT: jnlh .L{{.*}} 70 ; CHECK: br %r14 71 entry: 72 %res = fadd float %a, %b 73 %cmp = fcmp ueq float %res, 0.0 74 br i1 %cmp, label %exit, label %store 75 76 store: 77 store float %b, float *%dest 78 br label %exit 79 80 exit: 81 ret float %res 82 } 83 84 ; Subtraction also provides a zero-based CC value. 85 define float @f5(float %a, float %b, float *%dest) { 86 ; CHECK-LABEL: f5: 87 ; CHECK: seb %f0, 0(%r2) 88 ; CHECK-NEXT: jnhe .L{{.*}} 89 ; CHECK: br %r14 90 entry: 91 %cur = load float *%dest 92 %res = fsub float %a, %cur 93 %cmp = fcmp ult float %res, 0.0 94 br i1 %cmp, label %exit, label %store 95 96 store: 97 store float %b, float *%dest 98 br label %exit 99 100 exit: 101 ret float %res 102 } 103 104 ; Test the result of LOAD POSITIVE. 105 define float @f6(float %dummy, float %a, float *%dest) { 106 ; CHECK-LABEL: f6: 107 ; CHECK: lpebr %f0, %f2 108 ; CHECK-NEXT: jh .L{{.*}} 109 ; CHECK: br %r14 110 entry: 111 %res = call float @llvm.fabs.f32(float %a) 112 %cmp = fcmp ogt float %res, 0.0 113 br i1 %cmp, label %exit, label %store 114 115 store: 116 store float %res, float *%dest 117 br label %exit 118 119 exit: 120 ret float %res 121 } 122 123 ; Test the result of LOAD NEGATIVE. 124 define float @f7(float %dummy, float %a, float *%dest) { 125 ; CHECK-LABEL: f7: 126 ; CHECK: lnebr %f0, %f2 127 ; CHECK-NEXT: jl .L{{.*}} 128 ; CHECK: br %r14 129 entry: 130 %abs = call float @llvm.fabs.f32(float %a) 131 %res = fsub float -0.0, %abs 132 %cmp = fcmp olt float %res, 0.0 133 br i1 %cmp, label %exit, label %store 134 135 store: 136 store float %res, float *%dest 137 br label %exit 138 139 exit: 140 ret float %res 141 } 142 143 ; Test the result of LOAD COMPLEMENT. 144 define float @f8(float %dummy, float %a, float *%dest) { 145 ; CHECK-LABEL: f8: 146 ; CHECK: lcebr %f0, %f2 147 ; CHECK-NEXT: jle .L{{.*}} 148 ; CHECK: br %r14 149 entry: 150 %res = fsub float -0.0, %a 151 %cmp = fcmp ole float %res, 0.0 152 br i1 %cmp, label %exit, label %store 153 154 store: 155 store float %res, float *%dest 156 br label %exit 157 158 exit: 159 ret float %res 160 } 161 162 ; Multiplication (for example) does not modify CC. 163 define float @f9(float %a, float %b, float *%dest) { 164 ; CHECK-LABEL: f9: 165 ; CHECK: meebr %f0, %f2 166 ; CHECK-NEXT: ltebr %f0, %f0 167 ; CHECK-NEXT: jlh .L{{.*}} 168 ; CHECK: br %r14 169 entry: 170 %res = fmul float %a, %b 171 %cmp = fcmp one float %res, 0.0 172 br i1 %cmp, label %exit, label %store 173 174 store: 175 store float %b, float *%dest 176 br label %exit 177 178 exit: 179 ret float %res 180 } 181 182 ; Test a combination involving a CC-setting instruction followed by 183 ; a non-CC-setting instruction. 184 define float @f10(float %a, float %b, float %c, float *%dest) { 185 ; CHECK-LABEL: f10: 186 ; CHECK: aebr %f0, %f2 187 ; CHECK-NEXT: debr %f0, %f4 188 ; CHECK-NEXT: ltebr %f0, %f0 189 ; CHECK-NEXT: jne .L{{.*}} 190 ; CHECK: br %r14 191 entry: 192 %add = fadd float %a, %b 193 %res = fdiv float %add, %c 194 %cmp = fcmp une float %res, 0.0 195 br i1 %cmp, label %exit, label %store 196 197 store: 198 store float %b, float *%dest 199 br label %exit 200 201 exit: 202 ret float %res 203 } 204 205 ; Test a case where CC is set based on a different register from the 206 ; compare input. 207 define float @f11(float %a, float %b, float %c, float *%dest1, float *%dest2) { 208 ; CHECK-LABEL: f11: 209 ; CHECK: aebr %f0, %f2 210 ; CHECK-NEXT: sebr %f4, %f0 211 ; CHECK-NEXT: ste %f4, 0(%r2) 212 ; CHECK-NEXT: ltebr %f0, %f0 213 ; CHECK-NEXT: je .L{{.*}} 214 ; CHECK: br %r14 215 entry: 216 %add = fadd float %a, %b 217 %sub = fsub float %c, %add 218 store float %sub, float *%dest1 219 %cmp = fcmp oeq float %add, 0.0 220 br i1 %cmp, label %exit, label %store 221 222 store: 223 store float %sub, float *%dest2 224 br label %exit 225 226 exit: 227 ret float %add 228 } 229 230 ; Test that LER gets converted to LTEBR where useful. 231 define float @f12(float %dummy, float %val, float *%dest) { 232 ; CHECK-LABEL: f12: 233 ; CHECK: ltebr %f0, %f2 234 ; CHECK-NEXT: #APP 235 ; CHECK-NEXT: blah %f0 236 ; CHECK-NEXT: #NO_APP 237 ; CHECK-NEXT: jl .L{{.*}} 238 ; CHECK: br %r14 239 entry: 240 call void asm sideeffect "blah $0", "{f0}"(float %val) 241 %cmp = fcmp olt float %val, 0.0 242 br i1 %cmp, label %exit, label %store 243 244 store: 245 store float %val, float *%dest 246 br label %exit 247 248 exit: 249 ret float %val 250 } 251 252 ; Test that LDR gets converted to LTDBR where useful. 253 define double @f13(double %dummy, double %val, double *%dest) { 254 ; CHECK-LABEL: f13: 255 ; CHECK: ltdbr %f0, %f2 256 ; CHECK-NEXT: #APP 257 ; CHECK-NEXT: blah %f0 258 ; CHECK-NEXT: #NO_APP 259 ; CHECK-NEXT: jl .L{{.*}} 260 ; CHECK: br %r14 261 entry: 262 call void asm sideeffect "blah $0", "{f0}"(double %val) 263 %cmp = fcmp olt double %val, 0.0 264 br i1 %cmp, label %exit, label %store 265 266 store: 267 store double %val, double *%dest 268 br label %exit 269 270 exit: 271 ret double %val 272 } 273 274 ; Test that LXR gets converted to LTXBR where useful. 275 define void @f14(fp128 *%ptr1, fp128 *%ptr2) { 276 ; CHECK-LABEL: f14: 277 ; CHECK: ltxbr 278 ; CHECK-NEXT: dxbr 279 ; CHECK-NEXT: std 280 ; CHECK-NEXT: std 281 ; CHECK-NEXT: mxbr 282 ; CHECK-NEXT: std 283 ; CHECK-NEXT: std 284 ; CHECK-NEXT: jl .L{{.*}} 285 ; CHECK: br %r14 286 entry: 287 %val1 = load fp128 *%ptr1 288 %val2 = load fp128 *%ptr2 289 %div = fdiv fp128 %val1, %val2 290 store fp128 %div, fp128 *%ptr1 291 %mul = fmul fp128 %val1, %val2 292 store fp128 %mul, fp128 *%ptr2 293 %cmp = fcmp olt fp128 %val1, 0xL00000000000000000000000000000000 294 br i1 %cmp, label %exit, label %store 295 296 store: 297 call void asm sideeffect "blah", ""() 298 br label %exit 299 300 exit: 301 ret void 302 } 303 304 ; Test a case where it is the source rather than destination of LER that 305 ; we need. 306 define float @f15(float %val, float %dummy, float *%dest) { 307 ; CHECK-LABEL: f15: 308 ; CHECK: ltebr %f2, %f0 309 ; CHECK-NEXT: #APP 310 ; CHECK-NEXT: blah %f2 311 ; CHECK-NEXT: #NO_APP 312 ; CHECK-NEXT: jl .L{{.*}} 313 ; CHECK: br %r14 314 entry: 315 call void asm sideeffect "blah $0", "{f2}"(float %val) 316 %cmp = fcmp olt float %val, 0.0 317 br i1 %cmp, label %exit, label %store 318 319 store: 320 store float %val, float *%dest 321 br label %exit 322 323 exit: 324 ret float %val 325 } 326 327 ; Test a case where it is the source rather than destination of LDR that 328 ; we need. 329 define double @f16(double %val, double %dummy, double *%dest) { 330 ; CHECK-LABEL: f16: 331 ; CHECK: ltdbr %f2, %f0 332 ; CHECK-NEXT: #APP 333 ; CHECK-NEXT: blah %f2 334 ; CHECK-NEXT: #NO_APP 335 ; CHECK-NEXT: jl .L{{.*}} 336 ; CHECK: br %r14 337 entry: 338 call void asm sideeffect "blah $0", "{f2}"(double %val) 339 %cmp = fcmp olt double %val, 0.0 340 br i1 %cmp, label %exit, label %store 341 342 store: 343 store double %val, double *%dest 344 br label %exit 345 346 exit: 347 ret double %val 348 } 349