1 ; Test 32-bit floating-point comparison. The tests assume a z10 implementation 2 ; of select, using conditional branches rather than LOCGR. 3 ; 4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 5 6 declare float @foo() 7 8 ; Check comparison with registers. 9 define i64 @f1(i64 %a, i64 %b, float %f1, float %f2) { 10 ; CHECK-LABEL: f1: 11 ; CHECK: cebr %f0, %f2 12 ; CHECK-NEXT: je 13 ; CHECK: lgr %r2, %r3 14 ; CHECK: br %r14 15 %cond = fcmp oeq float %f1, %f2 16 %res = select i1 %cond, i64 %a, i64 %b 17 ret i64 %res 18 } 19 20 ; Check the low end of the CEB range. 21 define i64 @f2(i64 %a, i64 %b, float %f1, float *%ptr) { 22 ; CHECK-LABEL: f2: 23 ; CHECK: ceb %f0, 0(%r4) 24 ; CHECK-NEXT: je 25 ; CHECK: lgr %r2, %r3 26 ; CHECK: br %r14 27 %f2 = load float , float *%ptr 28 %cond = fcmp oeq float %f1, %f2 29 %res = select i1 %cond, i64 %a, i64 %b 30 ret i64 %res 31 } 32 33 ; Check the high end of the aligned CEB range. 34 define i64 @f3(i64 %a, i64 %b, float %f1, float *%base) { 35 ; CHECK-LABEL: f3: 36 ; CHECK: ceb %f0, 4092(%r4) 37 ; CHECK-NEXT: je 38 ; CHECK: lgr %r2, %r3 39 ; CHECK: br %r14 40 %ptr = getelementptr float, float *%base, i64 1023 41 %f2 = load float , float *%ptr 42 %cond = fcmp oeq float %f1, %f2 43 %res = select i1 %cond, i64 %a, i64 %b 44 ret i64 %res 45 } 46 47 ; Check the next word up, which needs separate address logic. 48 ; Other sequences besides this one would be OK. 49 define i64 @f4(i64 %a, i64 %b, float %f1, float *%base) { 50 ; CHECK-LABEL: f4: 51 ; CHECK: aghi %r4, 4096 52 ; CHECK: ceb %f0, 0(%r4) 53 ; CHECK-NEXT: je 54 ; CHECK: lgr %r2, %r3 55 ; CHECK: br %r14 56 %ptr = getelementptr float, float *%base, i64 1024 57 %f2 = load float , float *%ptr 58 %cond = fcmp oeq float %f1, %f2 59 %res = select i1 %cond, i64 %a, i64 %b 60 ret i64 %res 61 } 62 63 ; Check negative displacements, which also need separate address logic. 64 define i64 @f5(i64 %a, i64 %b, float %f1, float *%base) { 65 ; CHECK-LABEL: f5: 66 ; CHECK: aghi %r4, -4 67 ; CHECK: ceb %f0, 0(%r4) 68 ; CHECK-NEXT: je 69 ; CHECK: lgr %r2, %r3 70 ; CHECK: br %r14 71 %ptr = getelementptr float, float *%base, i64 -1 72 %f2 = load float , float *%ptr 73 %cond = fcmp oeq float %f1, %f2 74 %res = select i1 %cond, i64 %a, i64 %b 75 ret i64 %res 76 } 77 78 ; Check that CEB allows indices. 79 define i64 @f6(i64 %a, i64 %b, float %f1, float *%base, i64 %index) { 80 ; CHECK-LABEL: f6: 81 ; CHECK: sllg %r1, %r5, 2 82 ; CHECK: ceb %f0, 400(%r1,%r4) 83 ; CHECK-NEXT: je 84 ; CHECK: lgr %r2, %r3 85 ; CHECK: br %r14 86 %ptr1 = getelementptr float, float *%base, i64 %index 87 %ptr2 = getelementptr float, float *%ptr1, i64 100 88 %f2 = load float , float *%ptr2 89 %cond = fcmp oeq float %f1, %f2 90 %res = select i1 %cond, i64 %a, i64 %b 91 ret i64 %res 92 } 93 94 ; Check that comparisons of spilled values can use CEB rather than CEBR. 95 define float @f7(float *%ptr0) { 96 ; CHECK-LABEL: f7: 97 ; CHECK: brasl %r14, foo@PLT 98 ; CHECK: ceb {{%f[0-9]+}}, 16{{[04]}}(%r15) 99 ; CHECK: br %r14 100 %ptr1 = getelementptr float, float *%ptr0, i64 2 101 %ptr2 = getelementptr float, float *%ptr0, i64 4 102 %ptr3 = getelementptr float, float *%ptr0, i64 6 103 %ptr4 = getelementptr float, float *%ptr0, i64 8 104 %ptr5 = getelementptr float, float *%ptr0, i64 10 105 %ptr6 = getelementptr float, float *%ptr0, i64 12 106 %ptr7 = getelementptr float, float *%ptr0, i64 14 107 %ptr8 = getelementptr float, float *%ptr0, i64 16 108 %ptr9 = getelementptr float, float *%ptr0, i64 18 109 %ptr10 = getelementptr float, float *%ptr0, i64 20 110 111 %val0 = load float , float *%ptr0 112 %val1 = load float , float *%ptr1 113 %val2 = load float , float *%ptr2 114 %val3 = load float , float *%ptr3 115 %val4 = load float , float *%ptr4 116 %val5 = load float , float *%ptr5 117 %val6 = load float , float *%ptr6 118 %val7 = load float , float *%ptr7 119 %val8 = load float , float *%ptr8 120 %val9 = load float , float *%ptr9 121 %val10 = load float , float *%ptr10 122 123 %ret = call float @foo() 124 125 %cmp0 = fcmp olt float %ret, %val0 126 %cmp1 = fcmp olt float %ret, %val1 127 %cmp2 = fcmp olt float %ret, %val2 128 %cmp3 = fcmp olt float %ret, %val3 129 %cmp4 = fcmp olt float %ret, %val4 130 %cmp5 = fcmp olt float %ret, %val5 131 %cmp6 = fcmp olt float %ret, %val6 132 %cmp7 = fcmp olt float %ret, %val7 133 %cmp8 = fcmp olt float %ret, %val8 134 %cmp9 = fcmp olt float %ret, %val9 135 %cmp10 = fcmp olt float %ret, %val10 136 137 %sel0 = select i1 %cmp0, float %ret, float 0.0 138 %sel1 = select i1 %cmp1, float %sel0, float 1.0 139 %sel2 = select i1 %cmp2, float %sel1, float 2.0 140 %sel3 = select i1 %cmp3, float %sel2, float 3.0 141 %sel4 = select i1 %cmp4, float %sel3, float 4.0 142 %sel5 = select i1 %cmp5, float %sel4, float 5.0 143 %sel6 = select i1 %cmp6, float %sel5, float 6.0 144 %sel7 = select i1 %cmp7, float %sel6, float 7.0 145 %sel8 = select i1 %cmp8, float %sel7, float 8.0 146 %sel9 = select i1 %cmp9, float %sel8, float 9.0 147 %sel10 = select i1 %cmp10, float %sel9, float 10.0 148 149 ret float %sel10 150 } 151 152 ; Check comparison with zero. 153 define i64 @f8(i64 %a, i64 %b, float %f) { 154 ; CHECK-LABEL: f8: 155 ; CHECK: ltebr %f0, %f0 156 ; CHECK-NEXT: je 157 ; CHECK: lgr %r2, %r3 158 ; CHECK: br %r14 159 %cond = fcmp oeq float %f, 0.0 160 %res = select i1 %cond, i64 %a, i64 %b 161 ret i64 %res 162 } 163 164 ; Check the comparison can be reversed if that allows CEB to be used, 165 ; first with oeq. 166 define i64 @f9(i64 %a, i64 %b, float %f2, float *%ptr) { 167 ; CHECK-LABEL: f9: 168 ; CHECK: ceb %f0, 0(%r4) 169 ; CHECK-NEXT: je {{\.L.*}} 170 ; CHECK: lgr %r2, %r3 171 ; CHECK: br %r14 172 %f1 = load float , float *%ptr 173 %cond = fcmp oeq float %f1, %f2 174 %res = select i1 %cond, i64 %a, i64 %b 175 ret i64 %res 176 } 177 178 ; ...then one. 179 define i64 @f10(i64 %a, i64 %b, float %f2, float *%ptr) { 180 ; CHECK-LABEL: f10: 181 ; CHECK: ceb %f0, 0(%r4) 182 ; CHECK-NEXT: jlh {{\.L.*}} 183 ; CHECK: lgr %r2, %r3 184 ; CHECK: br %r14 185 %f1 = load float , float *%ptr 186 %cond = fcmp one float %f1, %f2 187 %res = select i1 %cond, i64 %a, i64 %b 188 ret i64 %res 189 } 190 191 ; ...then olt. 192 define i64 @f11(i64 %a, i64 %b, float %f2, float *%ptr) { 193 ; CHECK-LABEL: f11: 194 ; CHECK: ceb %f0, 0(%r4) 195 ; CHECK-NEXT: jh {{\.L.*}} 196 ; CHECK: lgr %r2, %r3 197 ; CHECK: br %r14 198 %f1 = load float , float *%ptr 199 %cond = fcmp olt float %f1, %f2 200 %res = select i1 %cond, i64 %a, i64 %b 201 ret i64 %res 202 } 203 204 ; ...then ole. 205 define i64 @f12(i64 %a, i64 %b, float %f2, float *%ptr) { 206 ; CHECK-LABEL: f12: 207 ; CHECK: ceb %f0, 0(%r4) 208 ; CHECK-NEXT: jhe {{\.L.*}} 209 ; CHECK: lgr %r2, %r3 210 ; CHECK: br %r14 211 %f1 = load float , float *%ptr 212 %cond = fcmp ole float %f1, %f2 213 %res = select i1 %cond, i64 %a, i64 %b 214 ret i64 %res 215 } 216 217 ; ...then oge. 218 define i64 @f13(i64 %a, i64 %b, float %f2, float *%ptr) { 219 ; CHECK-LABEL: f13: 220 ; CHECK: ceb %f0, 0(%r4) 221 ; CHECK-NEXT: jle {{\.L.*}} 222 ; CHECK: lgr %r2, %r3 223 ; CHECK: br %r14 224 %f1 = load float , float *%ptr 225 %cond = fcmp oge float %f1, %f2 226 %res = select i1 %cond, i64 %a, i64 %b 227 ret i64 %res 228 } 229 230 ; ...then ogt. 231 define i64 @f14(i64 %a, i64 %b, float %f2, float *%ptr) { 232 ; CHECK-LABEL: f14: 233 ; CHECK: ceb %f0, 0(%r4) 234 ; CHECK-NEXT: jl {{\.L.*}} 235 ; CHECK: lgr %r2, %r3 236 ; CHECK: br %r14 237 %f1 = load float , float *%ptr 238 %cond = fcmp ogt float %f1, %f2 239 %res = select i1 %cond, i64 %a, i64 %b 240 ret i64 %res 241 } 242 243 ; ...then ueq. 244 define i64 @f15(i64 %a, i64 %b, float %f2, float *%ptr) { 245 ; CHECK-LABEL: f15: 246 ; CHECK: ceb %f0, 0(%r4) 247 ; CHECK-NEXT: jnlh {{\.L.*}} 248 ; CHECK: lgr %r2, %r3 249 ; CHECK: br %r14 250 %f1 = load float , float *%ptr 251 %cond = fcmp ueq float %f1, %f2 252 %res = select i1 %cond, i64 %a, i64 %b 253 ret i64 %res 254 } 255 256 ; ...then une. 257 define i64 @f16(i64 %a, i64 %b, float %f2, float *%ptr) { 258 ; CHECK-LABEL: f16: 259 ; CHECK: ceb %f0, 0(%r4) 260 ; CHECK-NEXT: jne {{\.L.*}} 261 ; CHECK: lgr %r2, %r3 262 ; CHECK: br %r14 263 %f1 = load float , float *%ptr 264 %cond = fcmp une float %f1, %f2 265 %res = select i1 %cond, i64 %a, i64 %b 266 ret i64 %res 267 } 268 269 ; ...then ult. 270 define i64 @f17(i64 %a, i64 %b, float %f2, float *%ptr) { 271 ; CHECK-LABEL: f17: 272 ; CHECK: ceb %f0, 0(%r4) 273 ; CHECK-NEXT: jnle {{\.L.*}} 274 ; CHECK: lgr %r2, %r3 275 ; CHECK: br %r14 276 %f1 = load float , float *%ptr 277 %cond = fcmp ult float %f1, %f2 278 %res = select i1 %cond, i64 %a, i64 %b 279 ret i64 %res 280 } 281 282 ; ...then ule. 283 define i64 @f18(i64 %a, i64 %b, float %f2, float *%ptr) { 284 ; CHECK-LABEL: f18: 285 ; CHECK: ceb %f0, 0(%r4) 286 ; CHECK-NEXT: jnl {{\.L.*}} 287 ; CHECK: lgr %r2, %r3 288 ; CHECK: br %r14 289 %f1 = load float , float *%ptr 290 %cond = fcmp ule float %f1, %f2 291 %res = select i1 %cond, i64 %a, i64 %b 292 ret i64 %res 293 } 294 295 ; ...then uge. 296 define i64 @f19(i64 %a, i64 %b, float %f2, float *%ptr) { 297 ; CHECK-LABEL: f19: 298 ; CHECK: ceb %f0, 0(%r4) 299 ; CHECK-NEXT: jnh {{\.L.*}} 300 ; CHECK: lgr %r2, %r3 301 ; CHECK: br %r14 302 %f1 = load float , float *%ptr 303 %cond = fcmp uge float %f1, %f2 304 %res = select i1 %cond, i64 %a, i64 %b 305 ret i64 %res 306 } 307 308 ; ...then ugt. 309 define i64 @f20(i64 %a, i64 %b, float %f2, float *%ptr) { 310 ; CHECK-LABEL: f20: 311 ; CHECK: ceb %f0, 0(%r4) 312 ; CHECK-NEXT: jnhe {{\.L.*}} 313 ; CHECK: lgr %r2, %r3 314 ; CHECK: br %r14 315 %f1 = load float , float *%ptr 316 %cond = fcmp ugt float %f1, %f2 317 %res = select i1 %cond, i64 %a, i64 %b 318 ret i64 %res 319 } 320