457 lines · plain
1; Test 32-bit floating-point signaling comparison. The tests assume a z102; implementation 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 %s6; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 \7; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s8 9declare float @foo()10 11; Check comparison with registers.12define i64 @f0(i64 %a, i64 %b, half %f1, half %f2) #0 {13; CHECK-LABEL: f0:14; CHECK: brasl %r14, __extendhfsf2@PLT15; CHECK: brasl %r14, __extendhfsf2@PLT16; CHECK: kebr %f0, %f917; CHECK-SCALAR-NEXT: je18; CHECK-SCALAR: lgr %r13, %r1219; CHECK-SCALAR: lgr %r2, %r1320; CHECK-VECTOR: locgrne %r12, %r1321; CHECK-VECTOR: lgr %r2, %r1222; CHECK: br %r1423 %cond = call i1 @llvm.experimental.constrained.fcmps.f16(24 half %f1, half %f2,25 metadata !"oeq",26 metadata !"fpexcept.strict") #027 %res = select i1 %cond, i64 %a, i64 %b28 ret i64 %res29}30 31; Check comparison with registers.32define i64 @f1(i64 %a, i64 %b, float %f1, float %f2) #0 {33; CHECK-LABEL: f1:34; CHECK: kebr %f0, %f235; CHECK-SCALAR-NEXT: ber %r1436; CHECK-SCALAR: lgr %r2, %r337; CHECK-VECTOR-NEXT: locgrne %r2, %r338; CHECK: br %r1439 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(40 float %f1, float %f2,41 metadata !"oeq",42 metadata !"fpexcept.strict") #043 %res = select i1 %cond, i64 %a, i64 %b44 ret i64 %res45}46 47; Check the low end of the KEB range.48define i64 @f2(i64 %a, i64 %b, float %f1, ptr %ptr) #0 {49; CHECK-LABEL: f2:50; CHECK: keb %f0, 0(%r4)51; CHECK-SCALAR-NEXT: ber %r1452; CHECK-SCALAR: lgr %r2, %r353; CHECK-VECTOR-NEXT: locgrne %r2, %r354; CHECK: br %r1455 %f2 = load float, ptr %ptr56 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(57 float %f1, float %f2,58 metadata !"oeq",59 metadata !"fpexcept.strict") #060 %res = select i1 %cond, i64 %a, i64 %b61 ret i64 %res62}63 64; Check the high end of the aligned KEB range.65define i64 @f3(i64 %a, i64 %b, float %f1, ptr %base) #0 {66; CHECK-LABEL: f3:67; CHECK: keb %f0, 4092(%r4)68; CHECK-SCALAR-NEXT: ber %r1469; CHECK-SCALAR: lgr %r2, %r370; CHECK-VECTOR-NEXT: locgrne %r2, %r371; CHECK: br %r1472 %ptr = getelementptr float, ptr %base, i64 102373 %f2 = load float, ptr %ptr74 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(75 float %f1, float %f2,76 metadata !"oeq",77 metadata !"fpexcept.strict") #078 %res = select i1 %cond, i64 %a, i64 %b79 ret i64 %res80}81 82; Check the next word up, which needs separate address logic.83; Other sequences besides this one would be OK.84define i64 @f4(i64 %a, i64 %b, float %f1, ptr %base) #0 {85; CHECK-LABEL: f4:86; CHECK: aghi %r4, 409687; CHECK: keb %f0, 0(%r4)88; CHECK-SCALAR-NEXT: ber %r1489; CHECK-SCALAR: lgr %r2, %r390; CHECK-VECTOR-NEXT: locgrne %r2, %r391; CHECK: br %r1492 %ptr = getelementptr float, ptr %base, i64 102493 %f2 = load float, ptr %ptr94 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(95 float %f1, float %f2,96 metadata !"oeq",97 metadata !"fpexcept.strict") #098 %res = select i1 %cond, i64 %a, i64 %b99 ret i64 %res100}101 102; Check negative displacements, which also need separate address logic.103define i64 @f5(i64 %a, i64 %b, float %f1, ptr %base) #0 {104; CHECK-LABEL: f5:105; CHECK: aghi %r4, -4106; CHECK: keb %f0, 0(%r4)107; CHECK-SCALAR-NEXT: ber %r14108; CHECK-SCALAR: lgr %r2, %r3109; CHECK-VECTOR-NEXT: locgrne %r2, %r3110; CHECK: br %r14111 %ptr = getelementptr float, ptr %base, i64 -1112 %f2 = load float, ptr %ptr113 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(114 float %f1, float %f2,115 metadata !"oeq",116 metadata !"fpexcept.strict") #0117 %res = select i1 %cond, i64 %a, i64 %b118 ret i64 %res119}120 121; Check that KEB allows indices.122define i64 @f6(i64 %a, i64 %b, float %f1, ptr %base, i64 %index) #0 {123; CHECK-LABEL: f6:124; CHECK: sllg %r1, %r5, 2125; CHECK: keb %f0, 400(%r1,%r4)126; CHECK-SCALAR-NEXT: ber %r14127; CHECK-SCALAR: lgr %r2, %r3128; CHECK-VECTOR-NEXT: locgrne %r2, %r3129; CHECK: br %r14130 %ptr1 = getelementptr float, ptr %base, i64 %index131 %ptr2 = getelementptr float, ptr %ptr1, i64 100132 %f2 = load float, ptr %ptr2133 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(134 float %f1, float %f2,135 metadata !"oeq",136 metadata !"fpexcept.strict") #0137 %res = select i1 %cond, i64 %a, i64 %b138 ret i64 %res139}140 141; Check that comparisons of spilled values can use KEB rather than KEBR.142define float @f7(ptr %ptr0) #0 {143; CHECK-LABEL: f7:144; CHECK: brasl %r14, foo@PLT145; CHECK-SCALAR: keb {{%f[0-9]+}}, 16{{[04]}}(%r15)146; CHECK: br %r14147 %ptr1 = getelementptr float, ptr %ptr0, i64 2148 %ptr2 = getelementptr float, ptr %ptr0, i64 4149 %ptr3 = getelementptr float, ptr %ptr0, i64 6150 %ptr4 = getelementptr float, ptr %ptr0, i64 8151 %ptr5 = getelementptr float, ptr %ptr0, i64 10152 %ptr6 = getelementptr float, ptr %ptr0, i64 12153 %ptr7 = getelementptr float, ptr %ptr0, i64 14154 %ptr8 = getelementptr float, ptr %ptr0, i64 16155 %ptr9 = getelementptr float, ptr %ptr0, i64 18156 %ptr10 = getelementptr float, ptr %ptr0, i64 20157 158 %val0 = load float, ptr %ptr0159 %val1 = load float, ptr %ptr1160 %val2 = load float, ptr %ptr2161 %val3 = load float, ptr %ptr3162 %val4 = load float, ptr %ptr4163 %val5 = load float, ptr %ptr5164 %val6 = load float, ptr %ptr6165 %val7 = load float, ptr %ptr7166 %val8 = load float, ptr %ptr8167 %val9 = load float, ptr %ptr9168 %val10 = load float, ptr %ptr10169 170 %ret = call float @foo() #0171 172 %cmp0 = call i1 @llvm.experimental.constrained.fcmps.f32(173 float %ret, float %val0,174 metadata !"olt",175 metadata !"fpexcept.strict") #0176 %cmp1 = call i1 @llvm.experimental.constrained.fcmps.f32(177 float %ret, float %val1,178 metadata !"olt",179 metadata !"fpexcept.strict") #0180 %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f32(181 float %ret, float %val2,182 metadata !"olt",183 metadata !"fpexcept.strict") #0184 %cmp3 = call i1 @llvm.experimental.constrained.fcmps.f32(185 float %ret, float %val3,186 metadata !"olt",187 metadata !"fpexcept.strict") #0188 %cmp4 = call i1 @llvm.experimental.constrained.fcmps.f32(189 float %ret, float %val4,190 metadata !"olt",191 metadata !"fpexcept.strict") #0192 %cmp5 = call i1 @llvm.experimental.constrained.fcmps.f32(193 float %ret, float %val5,194 metadata !"olt",195 metadata !"fpexcept.strict") #0196 %cmp6 = call i1 @llvm.experimental.constrained.fcmps.f32(197 float %ret, float %val6,198 metadata !"olt",199 metadata !"fpexcept.strict") #0200 %cmp7 = call i1 @llvm.experimental.constrained.fcmps.f32(201 float %ret, float %val7,202 metadata !"olt",203 metadata !"fpexcept.strict") #0204 %cmp8 = call i1 @llvm.experimental.constrained.fcmps.f32(205 float %ret, float %val8,206 metadata !"olt",207 metadata !"fpexcept.strict") #0208 %cmp9 = call i1 @llvm.experimental.constrained.fcmps.f32(209 float %ret, float %val9,210 metadata !"olt",211 metadata !"fpexcept.strict") #0212 %cmp10 = call i1 @llvm.experimental.constrained.fcmps.f32(213 float %ret, float %val10,214 metadata !"olt",215 metadata !"fpexcept.strict") #0216 217 %sel0 = select i1 %cmp0, float %ret, float 0.0218 %sel1 = select i1 %cmp1, float %sel0, float 1.0219 %sel2 = select i1 %cmp2, float %sel1, float 2.0220 %sel3 = select i1 %cmp3, float %sel2, float 3.0221 %sel4 = select i1 %cmp4, float %sel3, float 4.0222 %sel5 = select i1 %cmp5, float %sel4, float 5.0223 %sel6 = select i1 %cmp6, float %sel5, float 6.0224 %sel7 = select i1 %cmp7, float %sel6, float 7.0225 %sel8 = select i1 %cmp8, float %sel7, float 8.0226 %sel9 = select i1 %cmp9, float %sel8, float 9.0227 %sel10 = select i1 %cmp10, float %sel9, float 10.0228 229 ret float %sel10230}231 232; Check comparison with zero - cannot use LOAD AND TEST.233define i64 @f8(i64 %a, i64 %b, float %f) #0 {234; CHECK-LABEL: f8:235; CHECK: lzer [[REG:%f[0-9]+]]236; CHECK-NEXT: kebr %f0, [[REG]]237; CHECK-SCALAR-NEXT: ber %r14238; CHECK-SCALAR: lgr %r2, %r3239; CHECK-VECTOR-NEXT: locgrne %r2, %r3240; CHECK: br %r14241 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(242 float %f, float 0.0,243 metadata !"oeq",244 metadata !"fpexcept.strict") #0245 %res = select i1 %cond, i64 %a, i64 %b246 ret i64 %res247}248 249; Check the comparison can be reversed if that allows KEB to be used,250; first with oeq.251define i64 @f9(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {252; CHECK-LABEL: f9:253; CHECK: keb %f0, 0(%r4)254; CHECK-SCALAR-NEXT: ber %r14255; CHECK-SCALAR: lgr %r2, %r3256; CHECK-VECTOR-NEXT: locgrne %r2, %r3257; CHECK: br %r14258 %f1 = load float, ptr %ptr259 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(260 float %f1, float %f2,261 metadata !"oeq",262 metadata !"fpexcept.strict") #0263 %res = select i1 %cond, i64 %a, i64 %b264 ret i64 %res265}266 267; ...then one.268define i64 @f10(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {269; CHECK-LABEL: f10:270; CHECK: keb %f0, 0(%r4)271; CHECK-SCALAR-NEXT: blhr %r14272; CHECK-SCALAR: lgr %r2, %r3273; CHECK-VECTOR-NEXT: locgrnlh %r2, %r3274; CHECK: br %r14275 %f1 = load float, ptr %ptr276 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(277 float %f1, float %f2,278 metadata !"one",279 metadata !"fpexcept.strict") #0280 %res = select i1 %cond, i64 %a, i64 %b281 ret i64 %res282}283 284; ...then olt.285define i64 @f11(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {286; CHECK-LABEL: f11:287; CHECK: keb %f0, 0(%r4)288; CHECK-SCALAR-NEXT: bhr %r14289; CHECK-SCALAR: lgr %r2, %r3290; CHECK-VECTOR-NEXT: locgrnh %r2, %r3291; CHECK: br %r14292 %f1 = load float, ptr %ptr293 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(294 float %f1, float %f2,295 metadata !"olt",296 metadata !"fpexcept.strict") #0297 %res = select i1 %cond, i64 %a, i64 %b298 ret i64 %res299}300 301; ...then ole.302define i64 @f12(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {303; CHECK-LABEL: f12:304; CHECK: keb %f0, 0(%r4)305; CHECK-SCALAR-NEXT: bher %r14306; CHECK-SCALAR: lgr %r2, %r3307; CHECK-VECTOR-NEXT: locgrnhe %r2, %r3308; CHECK: br %r14309 %f1 = load float, ptr %ptr310 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(311 float %f1, float %f2,312 metadata !"ole",313 metadata !"fpexcept.strict") #0314 %res = select i1 %cond, i64 %a, i64 %b315 ret i64 %res316}317 318; ...then oge.319define i64 @f13(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {320; CHECK-LABEL: f13:321; CHECK: keb %f0, 0(%r4)322; CHECK-SCALAR-NEXT: bler %r14323; CHECK-SCALAR: lgr %r2, %r3324; CHECK-VECTOR-NEXT: locgrnle %r2, %r3325; CHECK: br %r14326 %f1 = load float, ptr %ptr327 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(328 float %f1, float %f2,329 metadata !"oge",330 metadata !"fpexcept.strict") #0331 %res = select i1 %cond, i64 %a, i64 %b332 ret i64 %res333}334 335; ...then ogt.336define i64 @f14(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {337; CHECK-LABEL: f14:338; CHECK: keb %f0, 0(%r4)339; CHECK-SCALAR-NEXT: blr %r14340; CHECK-SCALAR: lgr %r2, %r3341; CHECK-VECTOR-NEXT: locgrnl %r2, %r3342; CHECK: br %r14343 %f1 = load float, ptr %ptr344 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(345 float %f1, float %f2,346 metadata !"ogt",347 metadata !"fpexcept.strict") #0348 %res = select i1 %cond, i64 %a, i64 %b349 ret i64 %res350}351 352; ...then ueq.353define i64 @f15(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {354; CHECK-LABEL: f15:355; CHECK: keb %f0, 0(%r4)356; CHECK-SCALAR-NEXT: bnlhr %r14357; CHECK-SCALAR: lgr %r2, %r3358; CHECK-VECTOR-NEXT: locgrlh %r2, %r3359; CHECK: br %r14360 %f1 = load float, ptr %ptr361 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(362 float %f1, float %f2,363 metadata !"ueq",364 metadata !"fpexcept.strict") #0365 %res = select i1 %cond, i64 %a, i64 %b366 ret i64 %res367}368 369; ...then une.370define i64 @f16(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {371; CHECK-LABEL: f16:372; CHECK: keb %f0, 0(%r4)373; CHECK-SCALAR-NEXT: bner %r14374; CHECK-SCALAR: lgr %r2, %r3375; CHECK-VECTOR-NEXT: locgre %r2, %r3376; CHECK: br %r14377 %f1 = load float, ptr %ptr378 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(379 float %f1, float %f2,380 metadata !"une",381 metadata !"fpexcept.strict") #0382 %res = select i1 %cond, i64 %a, i64 %b383 ret i64 %res384}385 386; ...then ult.387define i64 @f17(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {388; CHECK-LABEL: f17:389; CHECK: keb %f0, 0(%r4)390; CHECK-SCALAR-NEXT: bnler %r14391; CHECK-SCALAR: lgr %r2, %r3392; CHECK-VECTOR-NEXT: locgrle %r2, %r3393; CHECK: br %r14394 %f1 = load float, ptr %ptr395 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(396 float %f1, float %f2,397 metadata !"ult",398 metadata !"fpexcept.strict") #0399 %res = select i1 %cond, i64 %a, i64 %b400 ret i64 %res401}402 403; ...then ule.404define i64 @f18(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {405; CHECK-LABEL: f18:406; CHECK: keb %f0, 0(%r4)407; CHECK-SCALAR-NEXT: bnlr %r14408; CHECK-SCALAR: lgr %r2, %r3409; CHECK-VECTOR-NEXT: locgrl %r2, %r3410; CHECK: br %r14411 %f1 = load float, ptr %ptr412 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(413 float %f1, float %f2,414 metadata !"ule",415 metadata !"fpexcept.strict") #0416 %res = select i1 %cond, i64 %a, i64 %b417 ret i64 %res418}419 420; ...then uge.421define i64 @f19(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {422; CHECK-LABEL: f19:423; CHECK: keb %f0, 0(%r4)424; CHECK-SCALAR-NEXT: bnhr %r14425; CHECK-SCALAR: lgr %r2, %r3426; CHECK-VECTOR-NEXT: locgrh %r2, %r3427; CHECK: br %r14428 %f1 = load float, ptr %ptr429 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(430 float %f1, float %f2,431 metadata !"uge",432 metadata !"fpexcept.strict") #0433 %res = select i1 %cond, i64 %a, i64 %b434 ret i64 %res435}436 437; ...then ugt.438define i64 @f20(i64 %a, i64 %b, float %f2, ptr %ptr) #0 {439; CHECK-LABEL: f20:440; CHECK: keb %f0, 0(%r4)441; CHECK-SCALAR-NEXT: bnher %r14442; CHECK-SCALAR: lgr %r2, %r3443; CHECK-VECTOR-NEXT: locgrhe %r2, %r3444; CHECK: br %r14445 %f1 = load float, ptr %ptr446 %cond = call i1 @llvm.experimental.constrained.fcmps.f32(447 float %f1, float %f2,448 metadata !"ugt",449 metadata !"fpexcept.strict") #0450 %res = select i1 %cond, i64 %a, i64 %b451 ret i64 %res452}453 454attributes #0 = { strictfp }455 456declare i1 @llvm.experimental.constrained.fcmps.f32(float, float, metadata, metadata)457