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 6declare float @foo() 7 8; Check comparison with registers. 9define 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. 21define 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. 34define 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. 49define 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. 64define 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. 79define 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. 95define 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. 153define 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. 166define 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. 179define 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. 192define 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. 205define 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. 218define 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. 231define 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. 244define 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. 257define 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. 270define 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. 283define 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. 296define 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. 309define 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