brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.7 KiB · dfefc43 Raw
642 lines · plain
1; Test that floating-point strict compares are omitted if CC already has the2; right value.3;4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \5; RUN:   -enable-misched=0 -no-integrated-as | FileCheck %s6;7; We need -enable-misched=0 to make sure f12 and following routines really8; test the compare elimination pass.9 10 11declare float @llvm.fabs.f32(float %f)12 13; Test addition followed by EQ, which can use the CC result of the addition.14define float @f1(float %a, float %b, ptr %dest) #0 {15; CHECK-LABEL: f1:16; CHECK: aebr %f0, %f217; CHECK-NEXT: ber %r1418; CHECK: br %r1419entry:20  %res = call float @llvm.experimental.constrained.fadd.f32(21                        float %a, float %b,22                        metadata !"round.dynamic",23                        metadata !"fpexcept.strict") #024  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(25                                               float %res, float 0.0,26                                               metadata !"oeq",27                                               metadata !"fpexcept.strict") #028  br i1 %cmp, label %exit, label %store29 30store:31  store float %b, ptr %dest32  br label %exit33 34exit:35  ret float %res36}37 38; ...and again with LT.39define float @f2(float %a, float %b, ptr %dest) #0 {40; CHECK-LABEL: f2:41; CHECK: aebr %f0, %f242; CHECK-NEXT: blr %r1443; CHECK: br %r1444entry:45  %res = call float @llvm.experimental.constrained.fadd.f32(46                        float %a, float %b,47                        metadata !"round.dynamic",48                        metadata !"fpexcept.strict") #049  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(50                                               float %res, float 0.0,51                                               metadata !"olt",52                                               metadata !"fpexcept.strict") #053  br i1 %cmp, label %exit, label %store54 55store:56  store float %b, ptr %dest57  br label %exit58 59exit:60  ret float %res61}62 63; ...and again with GT.64define float @f3(float %a, float %b, ptr %dest) #0 {65; CHECK-LABEL: f3:66; CHECK: aebr %f0, %f267; CHECK-NEXT: bhr %r1468; CHECK: br %r1469entry:70  %res = call float @llvm.experimental.constrained.fadd.f32(71                        float %a, float %b,72                        metadata !"round.dynamic",73                        metadata !"fpexcept.strict") #074  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(75                                               float %res, float 0.0,76                                               metadata !"ogt",77                                               metadata !"fpexcept.strict") #078  br i1 %cmp, label %exit, label %store79 80store:81  store float %b, ptr %dest82  br label %exit83 84exit:85  ret float %res86}87 88; ...and again with UEQ.89define float @f4(float %a, float %b, ptr %dest) #0 {90; CHECK-LABEL: f4:91; CHECK: aebr %f0, %f292; CHECK-NEXT: bnlhr %r1493; CHECK: br %r1494entry:95  %res = call float @llvm.experimental.constrained.fadd.f32(96                        float %a, float %b,97                        metadata !"round.dynamic",98                        metadata !"fpexcept.strict") #099  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(100                                               float %res, float 0.0,101                                               metadata !"ueq",102                                               metadata !"fpexcept.strict") #0103  br i1 %cmp, label %exit, label %store104 105store:106  store float %b, ptr %dest107  br label %exit108 109exit:110  ret float %res111}112 113; Subtraction also provides a zero-based CC value.114define float @f5(float %a, float %b, ptr %dest) #0 {115; CHECK-LABEL: f5:116; CHECK: seb %f0, 0(%r2)117; CHECK-NEXT: bnher %r14118; CHECK: br %r14119entry:120  %cur = load float, ptr %dest121  %res = call float @llvm.experimental.constrained.fsub.f32(122                        float %a, float %cur,123                        metadata !"round.dynamic",124                        metadata !"fpexcept.strict") #0125  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(126                                               float %res, float 0.0,127                                               metadata !"ult",128                                               metadata !"fpexcept.strict") #0129  br i1 %cmp, label %exit, label %store130 131store:132  store float %b, ptr %dest133  br label %exit134 135exit:136  ret float %res137}138 139; Test the result of LOAD POSITIVE.  We cannot omit the LTEBR.140define float @f6(float %dummy, float %a, ptr %dest) #0 {141; CHECK-LABEL: f6:142; CHECK: lpdfr %f0, %f2143; CHECK-NEXT: ltebr %f1, %f0144; CHECK-NEXT: bhr %r14145; CHECK: br %r14146entry:147  %res = call float @llvm.fabs.f32(float %a) #0148  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(149                                               float %res, float 0.0,150                                               metadata !"ogt",151                                               metadata !"fpexcept.strict") #0152  br i1 %cmp, label %exit, label %store153 154store:155  store float %res, ptr %dest156  br label %exit157 158exit:159  ret float %res160}161 162; Test the result of LOAD NEGATIVE.  We cannot omit the LTEBR.163define float @f7(float %dummy, float %a, ptr %dest) #0 {164; CHECK-LABEL: f7:165; CHECK: lndfr %f0, %f2166; CHECK-NEXT: ltebr %f1, %f0167; CHECK-NEXT: blr %r14168; CHECK: br %r14169entry:170  %abs = call float @llvm.fabs.f32(float %a) #0171  %res = fneg float %abs172  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(173                                               float %res, float 0.0,174                                               metadata !"olt",175                                               metadata !"fpexcept.strict") #0176  br i1 %cmp, label %exit, label %store177 178store:179  store float %res, ptr %dest180  br label %exit181 182exit:183  ret float %res184}185 186; Test the result of LOAD COMPLEMENT.  We cannot omit the LTEBR.187define float @f8(float %dummy, float %a, ptr %dest) #0 {188; CHECK-LABEL: f8:189; CHECK: lcdfr %f0, %f2190; CHECK-NEXT: ltebr %f1, %f0191; CHECK-NEXT: bler %r14192; CHECK: br %r14193entry:194  %res = fneg float %a195  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(196                                               float %res, float 0.0,197                                               metadata !"ole",198                                               metadata !"fpexcept.strict") #0199  br i1 %cmp, label %exit, label %store200 201store:202  store float %res, ptr %dest203  br label %exit204 205exit:206  ret float %res207}208 209; Multiplication (for example) does not modify CC.210define float @f9(float %a, float %b, ptr %dest) #0 {211; CHECK-LABEL: f9:212; CHECK: meebr %f0, %f2213; CHECK-NEXT: ltebr %f1, %f0214; CHECK-NEXT: blhr %r14215; CHECK: br %r14216entry:217  %res = call float @llvm.experimental.constrained.fmul.f32(218                        float %a, float %b,219                        metadata !"round.dynamic",220                        metadata !"fpexcept.strict") #0221  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(222                                               float %res, float 0.0,223                                               metadata !"one",224                                               metadata !"fpexcept.strict") #0225  br i1 %cmp, label %exit, label %store226 227store:228  store float %b, ptr %dest229  br label %exit230 231exit:232  ret float %res233}234 235; Test a combination involving a CC-setting instruction followed by236; a non-CC-setting instruction.237define float @f10(float %a, float %b, float %c, ptr %dest) #0 {238; CHECK-LABEL: f10:239; CHECK: aebr %f0, %f2240; CHECK-NEXT: debr %f0, %f4241; CHECK-NEXT: ltebr %f1, %f0242; CHECK-NEXT: bner %r14243; CHECK: br %r14244entry:245  %add = call float @llvm.experimental.constrained.fadd.f32(246                        float %a, float %b,247                        metadata !"round.dynamic",248                        metadata !"fpexcept.strict") #0249  %res = call float @llvm.experimental.constrained.fdiv.f32(250                        float %add, float %c,251                        metadata !"round.dynamic",252                        metadata !"fpexcept.strict") #0253  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(254                                               float %res, float 0.0,255                                               metadata !"une",256                                               metadata !"fpexcept.strict") #0257  br i1 %cmp, label %exit, label %store258 259store:260  store float %b, ptr %dest261  br label %exit262 263exit:264  ret float %res265}266 267; Test a case where CC is set based on a different register from the268; compare input.269define float @f11(float %a, float %b, float %c, ptr %dest1, ptr %dest2) #0 {270; CHECK-LABEL: f11:271; CHECK: aebr %f0, %f2272; CHECK-NEXT: sebr %f4, %f0273; CHECK-DAG: ste %f4, 0(%r2)274; CHECK-DAG: ltebr %f1, %f0275; CHECK-NEXT: ber %r14276; CHECK: br %r14277entry:278  %add = call float @llvm.experimental.constrained.fadd.f32(279                        float %a, float %b,280                        metadata !"round.dynamic",281                        metadata !"fpexcept.strict") #0282  %sub = call float @llvm.experimental.constrained.fsub.f32(283                        float %c, float %add,284                        metadata !"round.dynamic",285                        metadata !"fpexcept.strict") #0286  store float %sub, ptr %dest1287  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(288                                               float %add, float 0.0,289                                               metadata !"oeq",290                                               metadata !"fpexcept.strict") #0291  br i1 %cmp, label %exit, label %store292 293store:294  store float %sub, ptr %dest2295  br label %exit296 297exit:298  ret float %add299}300 301define half @f12_half(half %dummy, half %val) #0 {302; CHECK-LABEL: f12_half:303; CHECK:      ler %f9, %f2304; CHECK-NEXT: ler %f0, %f2305; CHECK-NEXT: #APP306; CHECK-NEXT: ler %f8, %f0307; CHECK-NEXT: #NO_APP308; CHECK-NEXT: lzer %f0309; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT310; CHECK-NEXT: ler %f10, %f0311; CHECK-NEXT: ler %f0, %f9312; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT313; CHECK-NEXT: cebr %f0, %f10314; CHECK-NEXT: jl .LBB11_2315; CHECK-NEXT:# %bb.1:        # %store316; CHECK-NEXT: #APP317; CHECK-NEXT: blah318; CHECK-NEXT: #NO_APP319; CHECK-NEXT:.LBB11_2:        # %exit320; CHECK-NEXT: ler %f0, %f8321; CHECK:      br  %r14322entry:323  %ret = call half asm "ler $0, $1", "=f,{f0}"(half %val) #0324  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(325                                               half %val, half 0.0,326                                               metadata !"olt",327                                               metadata !"fpexcept.strict") #0328  br i1 %cmp, label %exit, label %store329 330store:331  call void asm sideeffect "blah", ""() #0332  br label %exit333 334exit:335  ret half %ret336}337 338; Test that LER does not get converted to LTEBR as %f0 is live after it.339define float @f12(float %dummy, float %val) #0 {340; CHECK-LABEL: f12:341; CHECK: ler %f0, %f2342; CHECK-NEXT: #APP343; CHECK-NEXT: blah %f0344; CHECK-NEXT: #NO_APP345; CHECK-NEXT: ltebr %f1, %f2346; CHECK-NEXT: blr %r14347; CHECK: br %r14348entry:349  %ret = call float asm "$0 = blah $1", "=f,{f0}"(float %val) #0350  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(351                                               float %val, float 0.0,352                                               metadata !"olt",353                                               metadata !"fpexcept.strict") #0354  br i1 %cmp, label %exit, label %store355 356store:357  call void asm sideeffect "blah", ""() #0358  br label %exit359 360exit:361  ret float %ret362}363 364; Test that LDR does not get converted to LTDBR as %f0 is live after it.365define double @f13(double %dummy, double %val) #0 {366; CHECK-LABEL: f13:367; CHECK: ldr %f0, %f2368; CHECK-NEXT: #APP369; CHECK-NEXT: blah %f0370; CHECK-NEXT: #NO_APP371; CHECK-NEXT: ltdbr %f1, %f2372; CHECK-NEXT: blr %r14373; CHECK: br %r14374entry:375  %ret = call double asm "blah $1", "=f,{f0}"(double %val) #0376  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(377                                               double %val, double 0.0,378                                               metadata !"olt",379                                               metadata !"fpexcept.strict") #0380  br i1 %cmp, label %exit, label %store381 382store:383  call void asm sideeffect "blah", ""() #0384  br label %exit385 386exit:387  ret double %ret388}389 390; Test that LXR does not get converted to LTXBR as %f4 is live after it.391define void @f14(ptr %ptr1, ptr %ptr2) #0 {392; CHECK-LABEL: f14:393; CHECK: lxr394; CHECK-NEXT: dxbr395; CHECK-NEXT: std396; CHECK-NEXT: std397; CHECK-NEXT: mxbr398; CHECK-NEXT: std399; CHECK-NEXT: std400; CHECK-NEXT: ltxbr401; CHECK-NEXT: blr %r14402; CHECK: br %r14403entry:404  %val1 = load fp128, ptr %ptr1405  %val2 = load fp128, ptr %ptr2406  %div = fdiv fp128 %val1, %val2407  store fp128 %div, ptr %ptr1408  %mul = fmul fp128 %val1, %val2409  store fp128 %mul, ptr %ptr2410  %cmp = call i1 @llvm.experimental.constrained.fcmp.f128(411                                               fp128 %val1, fp128 0xL00000000000000000000000000000000,412                                               metadata !"olt",413                                               metadata !"fpexcept.strict") #0414  br i1 %cmp, label %exit, label %store415 416store:417  call void asm sideeffect "blah", ""() #0418  br label %exit419 420exit:421  ret void422}423 424define half @f15_half(half %val, half %dummy) #0 {425; CHECK-LABEL: f15_half:426; CHECK:      ler %f9, %f0427; CHECK-NEXT: ler %f2, %f0428; CHECK-NEXT: #APP429; CHECK-NEXT: ler %f8, %f2430; CHECK-NEXT: #NO_APP431; CHECK-NEXT: lzer %f0432; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT433; CHECK-NEXT: ler %f10, %f0434; CHECK-NEXT: ler %f0, %f9435; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT436; CHECK-NEXT: cebr %f0, %f10437; CHECK-NEXT: jl .LBB15_2438; CHECK-NEXT:# %bb.1:          # %store439; CHECK-NEXT: #APP440; CHECK-NEXT: blah441; CHECK-NEXT: #NO_APP442; CHECK-NEXT:.LBB15_2:         # %exit443; CHECK-NEXT: ler %f0, %f8444; CHECK: br %r14445entry:446  %ret = call half asm "ler $0, $1", "=f,{f2}"(half %val) #0447  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(448                                               half %val, half 0.0,449                                               metadata !"olt",450                                               metadata !"fpexcept.strict") #0451  br i1 %cmp, label %exit, label %store452 453store:454  call void asm sideeffect "blah", ""() #0455  br label %exit456 457exit:458  ret half %ret459}460 461; Test a case where it is the source rather than destination of LER that462; we need, but cannot convert the LER.463define float @f15(float %val, float %dummy) #0 {464; CHECK-LABEL: f15:465; CHECK: ler %f2, %f0466; CHECK-NEXT: #APP467; CHECK-NEXT: blah %f2468; CHECK-NEXT: #NO_APP469; CHECK-NEXT: ltebr %f1, %f2470; CHECK-NEXT: blr %r14471; CHECK: br %r14472entry:473  %ret = call float asm "blah $1", "=f,{f2}"(float %val) #0474  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(475                                               float %val, float 0.0,476                                               metadata !"olt",477                                               metadata !"fpexcept.strict") #0478  br i1 %cmp, label %exit, label %store479 480store:481  call void asm sideeffect "blah", ""() #0482  br label %exit483 484exit:485  ret float %ret486}487 488; Test a case where it is the source rather than destination of LDR that489; we need, but cannot convert the LDR.490define double @f16(double %val, double %dummy) #0 {491; CHECK-LABEL: f16:492; CHECK: ldr %f2, %f0493; CHECK-NEXT: #APP494; CHECK-NEXT: blah %f2495; CHECK-NEXT: #NO_APP496; CHECK-NEXT: ltdbr %f1, %f2497; CHECK-NEXT: blr %r14498; CHECK: br %r14499entry:500  %ret = call double asm "blah $1", "=f,{f2}"(double %val) #0501  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(502                                               double %val, double 0.0,503                                               metadata !"olt",504                                               metadata !"fpexcept.strict") #0505  br i1 %cmp, label %exit, label %store506 507store:508  call void asm sideeffect "blah", ""() #0509  br label %exit510 511exit:512  ret double %ret513}514 515; Repeat f2 with a comparison against -0.516define float @f17(float %a, float %b, ptr %dest) #0 {517; CHECK-LABEL: f17:518; CHECK: aebr %f0, %f2519; CHECK-NEXT: blr %r14520; CHECK: br %r14521entry:522  %res = call float @llvm.experimental.constrained.fadd.f32(523                        float %a, float %b,524                        metadata !"round.dynamic",525                        metadata !"fpexcept.strict") #0526  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(527                                               float %res, float -0.0,528                                               metadata !"olt",529                                               metadata !"fpexcept.strict") #0530  br i1 %cmp, label %exit, label %store531 532store:533  store float %b, ptr %dest534  br label %exit535 536exit:537  ret float %res538}539 540; Verify that we cannot omit the compare if there may be an intervening541; change to the exception flags.542define float @f18(float %a, float %b, ptr %dest) #0 {543; CHECK-LABEL: f18:544; CHECK: aebr %f0, %f2545; CHECK: ltebr %f1, %f0546; CHECK-NEXT: ber %r14547; CHECK: br %r14548entry:549  %res = call float @llvm.experimental.constrained.fadd.f32(550                        float %a, float %b,551                        metadata !"round.dynamic",552                        metadata !"fpexcept.strict") #0553  call void asm sideeffect "blah", ""() #0554  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(555                                               float %res, float 0.0,556                                               metadata !"oeq",557                                               metadata !"fpexcept.strict") #0558  br i1 %cmp, label %exit, label %store559 560store:561  store float %b, ptr %dest562  br label %exit563 564exit:565  ret float %res566}567 568define half @f19_half(half %dummy, half %val) #0 {569; CHECK-LABEL: f19_half:570; CHECK:      ler %f9, %f2571; CHECK-NEXT: ler %f0, %f2572; CHECK-NEXT: #APP573; CHECK-NEXT: ler %f8, %f0574; CHECK-NEXT: #NO_APP575; CHECK-NEXT: lzer %f0576; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT577; CHECK-NEXT: ler %f10, %f0578; CHECK-NEXT: ler %f0, %f9579; CHECK-NEXT: brasl %r14, __extendhfsf2@PLT580; CHECK-NEXT: cebr %f0, %f10581; CHECK-NEXT: jl .LBB20_2582; CHECK-NEXT:# %bb.1:           # %store583; CHECK-NEXT: #APP584; CHECK-NEXT: blah585; CHECK-NEXT: #NO_APP586; CHECK-NEXT:.LBB20_2:          # %exit587; CHECK-NEXT: ler %f0, %f8588; CHECK: br %r14589entry:590  %ret = call half asm sideeffect "ler $0, $1", "=f,{f0}"(half %val) #0591  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(592                                               half %val, half 0.0,593                                               metadata !"olt",594                                               metadata !"fpexcept.strict") #0595  br i1 %cmp, label %exit, label %store596 597store:598  call void asm sideeffect "blah", ""() #0599  br label %exit600 601exit:602  ret half %ret603}604 605; Verify that we cannot convert LER to LTEBR and omit the compare if606; there may be an intervening change to the exception flags.607define float @f19(float %dummy, float %val) #0 {608; CHECK-LABEL: f19:609; CHECK: ler %f0, %f2610; CHECK-NEXT: #APP611; CHECK-NEXT: blah %f0612; CHECK-NEXT: #NO_APP613; CHECK-NEXT: ltebr %f1, %f2614; CHECK-NEXT: blr %r14615; CHECK: br %r14616entry:617  %ret = call float asm sideeffect "blah $1", "=f,{f0}"(float %val) #0618  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(619                                               float %val, float 0.0,620                                               metadata !"olt",621                                               metadata !"fpexcept.strict") #0622  br i1 %cmp, label %exit, label %store623 624store:625  call void asm sideeffect "blah", ""() #0626  br label %exit627 628exit:629  ret float %ret630}631 632attributes #0 = { strictfp }633 634declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)635declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)636declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata)637declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata)638declare i1 @llvm.experimental.constrained.fcmp.f16(half, half, metadata, metadata)639declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata)640declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata)641declare i1 @llvm.experimental.constrained.fcmp.f128(fp128, fp128, metadata, metadata)642