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