332 lines · plain
1; RUN: llc < %s -mcpu=cortex-a57 -aarch64-a57-fp-load-balancing-override=1 -aarch64-a57-fp-load-balancing-force-all -enable-misched=false -enable-post-misched=false | FileCheck %s --check-prefix CHECK --check-prefix CHECK-EVEN2; RUN: llc < %s -mcpu=cortex-a57 -aarch64-a57-fp-load-balancing-override=2 -aarch64-a57-fp-load-balancing-force-all -enable-misched=false -enable-post-misched=false | FileCheck %s --check-prefix CHECK --check-prefix CHECK-ODD3; RUN: llc < %s -mcpu=cortex-a53 -aarch64-a57-fp-load-balancing-override=1 -aarch64-a57-fp-load-balancing-force-all -enable-misched=false -enable-post-misched=false | FileCheck %s --check-prefix CHECK --check-prefix CHECK-EVEN4; RUN: llc < %s -mcpu=cortex-a53 -aarch64-a57-fp-load-balancing-override=2 -aarch64-a57-fp-load-balancing-force-all -enable-misched=false -enable-post-misched=false | FileCheck %s --check-prefix CHECK --check-prefix CHECK-ODD5 6; The following tests use the balance-fp-ops feature, and should be independent of7; the target cpu.8 9; RUN: llc < %s -mtriple=aarch64 -mattr=+balance-fp-ops -aarch64-a57-fp-load-balancing-override=1 -aarch64-a57-fp-load-balancing-force-all -enable-misched=false -enable-post-misched=false | FileCheck %s --check-prefix CHECK --check-prefix CHECK-EVEN10; RUN: llc < %s -mtriple=aarch64 -mattr=+balance-fp-ops -aarch64-a57-fp-load-balancing-override=2 -aarch64-a57-fp-load-balancing-force-all -enable-misched=false -enable-post-misched=false | FileCheck %s --check-prefix CHECK --check-prefix CHECK-ODD11 12; Test the AArch64A57FPLoadBalancing pass. This pass relies heavily on register allocation, so13; our test strategy is to:14; * Force the pass to always perform register swapping even if the dest register is of the15; correct color already (-force-all)16; * Force the pass to ignore all hints it obtained from regalloc (-deterministic-balance),17; and run it twice, once where it always hints odd, and once where it always hints even.18;19; We then use regex magic to check that in the two cases the register allocation is20; different; this is what gives us the testing coverage and distinguishes cases where21; the pass has done some work versus accidental regalloc.22 23target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"24target triple = "aarch64"25 26; Non-overlapping groups - shouldn't need any changing at all.27 28; CHECK-LABEL: f1:29; CHECK-EVEN: fmadd [[x:d[0-9]*[02468]]]30; CHECK-ODD: fmadd [[x:d[0-9]*[13579]]]31; CHECK: fmadd [[x]]32; CHECK: fmsub [[x]]33; CHECK: fmadd [[x]]34; CHECK: str [[x]]35 36define void @f1(ptr nocapture readonly %p, ptr nocapture %q) #0 {37entry:38 %0 = load double, ptr %p, align 839 %arrayidx1 = getelementptr inbounds double, ptr %p, i64 140 %1 = load double, ptr %arrayidx1, align 841 %arrayidx2 = getelementptr inbounds double, ptr %p, i64 242 %2 = load double, ptr %arrayidx2, align 843 %arrayidx3 = getelementptr inbounds double, ptr %p, i64 344 %3 = load double, ptr %arrayidx3, align 845 %arrayidx4 = getelementptr inbounds double, ptr %p, i64 446 %4 = load double, ptr %arrayidx4, align 847 %mul = fmul fast double %0, %148 %add = fadd fast double %mul, %449 %mul5 = fmul fast double %1, %250 %add6 = fadd fast double %mul5, %add51 %mul7 = fmul fast double %1, %352 %sub = fsub fast double %add6, %mul753 %mul8 = fmul fast double %2, %354 %add9 = fadd fast double %mul8, %sub55 store double %add9, ptr %q, align 856 %arrayidx11 = getelementptr inbounds double, ptr %p, i64 557 %5 = load double, ptr %arrayidx11, align 858 %arrayidx12 = getelementptr inbounds double, ptr %p, i64 659 %6 = load double, ptr %arrayidx12, align 860 %arrayidx13 = getelementptr inbounds double, ptr %p, i64 761 %7 = load double, ptr %arrayidx13, align 862 %mul15 = fmul fast double %6, %763 %mul16 = fmul fast double %0, %564 %add17 = fadd fast double %mul16, %mul1565 %mul18 = fmul fast double %5, %666 %add19 = fadd fast double %mul18, %add1767 %arrayidx20 = getelementptr inbounds double, ptr %q, i64 168 store double %add19, ptr %arrayidx20, align 869 ret void70}71 72; Overlapping groups - coloring needed.73 74; CHECK-LABEL: f2:75; CHECK-EVEN: fmadd [[x:d[0-9]*[02468]]]76; CHECK-EVEN: fmul [[y:d[0-9]*[13579]]]77; CHECK-ODD: fmadd [[x:d[0-9]*[13579]]]78; CHECK-ODD: fmul [[y:d[0-9]*[02468]]]79; CHECK: fmadd [[x]]80; CHECK: fmadd [[y]]81; CHECK: fmsub [[x]]82; CHECK: fmadd [[y]]83; CHECK: fmadd [[x]]84; CHECK: stp [[x]], [[y]]85 86define void @f2(ptr nocapture readonly %p, ptr nocapture %q) #0 {87entry:88 %0 = load double, ptr %p, align 889 %arrayidx1 = getelementptr inbounds double, ptr %p, i64 190 %1 = load double, ptr %arrayidx1, align 891 %arrayidx2 = getelementptr inbounds double, ptr %p, i64 292 %2 = load double, ptr %arrayidx2, align 893 %arrayidx3 = getelementptr inbounds double, ptr %p, i64 394 %3 = load double, ptr %arrayidx3, align 895 %arrayidx4 = getelementptr inbounds double, ptr %p, i64 496 %4 = load double, ptr %arrayidx4, align 897 %arrayidx5 = getelementptr inbounds double, ptr %p, i64 598 %5 = load double, ptr %arrayidx5, align 899 %arrayidx6 = getelementptr inbounds double, ptr %p, i64 6100 %6 = load double, ptr %arrayidx6, align 8101 %arrayidx7 = getelementptr inbounds double, ptr %p, i64 7102 %7 = load double, ptr %arrayidx7, align 8103 %mul = fmul fast double %0, %1104 %add = fadd fast double %mul, %7105 %mul8 = fmul fast double %5, %6106 %mul9 = fmul fast double %1, %2107 %add10 = fadd fast double %mul9, %add108 %mul11 = fmul fast double %3, %4109 %add12 = fadd fast double %mul11, %mul8110 %mul13 = fmul fast double %1, %3111 %sub = fsub fast double %add10, %mul13112 %mul14 = fmul fast double %4, %5113 %add15 = fadd fast double %mul14, %add12114 %mul16 = fmul fast double %2, %3115 %add17 = fadd fast double %mul16, %sub116 store double %add17, ptr %q, align 8117 %arrayidx19 = getelementptr inbounds double, ptr %q, i64 1118 store double %add15, ptr %arrayidx19, align 8119 ret void120}121 122; Dest register is live on block exit - fixup needed.123 124; CHECK-LABEL: f3:125; CHECK-EVEN: fmadd [[x:d[0-9]*[02468]]]126; CHECK-ODD: fmadd [[x:d[0-9]*[13579]]]127; CHECK: fmadd [[x]]128; CHECK: fmsub [[x]]129; CHECK: fmadd [[y:d[0-9]+]], {{.*}}, [[x]]130; CHECK: str [[y]]131 132define void @f3(ptr nocapture readonly %p, ptr nocapture %q) #0 {133entry:134 %0 = load double, ptr %p, align 8135 %arrayidx1 = getelementptr inbounds double, ptr %p, i64 1136 %1 = load double, ptr %arrayidx1, align 8137 %arrayidx2 = getelementptr inbounds double, ptr %p, i64 2138 %2 = load double, ptr %arrayidx2, align 8139 %arrayidx3 = getelementptr inbounds double, ptr %p, i64 3140 %3 = load double, ptr %arrayidx3, align 8141 %arrayidx4 = getelementptr inbounds double, ptr %p, i64 4142 %4 = load double, ptr %arrayidx4, align 8143 %mul = fmul fast double %0, %1144 %add = fadd fast double %mul, %4145 %mul5 = fmul fast double %1, %2146 %add6 = fadd fast double %mul5, %add147 %mul7 = fmul fast double %1, %3148 %sub = fsub fast double %add6, %mul7149 %mul8 = fmul fast double %2, %3150 %add9 = fadd fast double %mul8, %sub151 %cmp = fcmp oeq double %3, 0.000000e+00152 br i1 %cmp, label %if.then, label %if.end153 154if.then: ; preds = %entry155 tail call void @g() #2156 br label %if.end157 158if.end: ; preds = %if.then, %entry159 store double %add9, ptr %q, align 8160 ret void161}162 163declare void @g(...) #1164 165; Single precision version of f2.166 167; CHECK-LABEL: f4:168; CHECK-EVEN: fmadd [[x:s[0-9]*[02468]]]169; CHECK-EVEN: fmul [[y:s[0-9]*[13579]]]170; CHECK-ODD: fmadd [[x:s[0-9]*[13579]]]171; CHECK-ODD: fmul [[y:s[0-9]*[02468]]]172; CHECK: fmadd [[x]]173; CHECK: fmadd [[y]]174; CHECK: fmsub [[x]]175; CHECK: fmadd [[y]]176; CHECK: fmadd [[x]]177; CHECK: stp [[x]], [[y]]178 179define void @f4(ptr nocapture readonly %p, ptr nocapture %q) #0 {180entry:181 %0 = load float, ptr %p, align 4182 %arrayidx1 = getelementptr inbounds float, ptr %p, i64 1183 %1 = load float, ptr %arrayidx1, align 4184 %arrayidx2 = getelementptr inbounds float, ptr %p, i64 2185 %2 = load float, ptr %arrayidx2, align 4186 %arrayidx3 = getelementptr inbounds float, ptr %p, i64 3187 %3 = load float, ptr %arrayidx3, align 4188 %arrayidx4 = getelementptr inbounds float, ptr %p, i64 4189 %4 = load float, ptr %arrayidx4, align 4190 %arrayidx5 = getelementptr inbounds float, ptr %p, i64 5191 %5 = load float, ptr %arrayidx5, align 4192 %arrayidx6 = getelementptr inbounds float, ptr %p, i64 6193 %6 = load float, ptr %arrayidx6, align 4194 %arrayidx7 = getelementptr inbounds float, ptr %p, i64 7195 %7 = load float, ptr %arrayidx7, align 4196 %mul = fmul fast float %0, %1197 %add = fadd fast float %mul, %7198 %mul8 = fmul fast float %5, %6199 %mul9 = fmul fast float %1, %2200 %add10 = fadd fast float %mul9, %add201 %mul11 = fmul fast float %3, %4202 %add12 = fadd fast float %mul11, %mul8203 %mul13 = fmul fast float %1, %3204 %sub = fsub fast float %add10, %mul13205 %mul14 = fmul fast float %4, %5206 %add15 = fadd fast float %mul14, %add12207 %mul16 = fmul fast float %2, %3208 %add17 = fadd fast float %mul16, %sub209 store float %add17, ptr %q, align 4210 %arrayidx19 = getelementptr inbounds float, ptr %q, i64 1211 store float %add15, ptr %arrayidx19, align 4212 ret void213}214 215; Single precision version of f3216 217; CHECK-LABEL: f5:218; CHECK-EVEN: fmadd [[x:s[0-9]*[02468]]]219; CHECK-ODD: fmadd [[x:s[0-9]*[13579]]]220; CHECK: fmadd [[x]]221; CHECK: fmsub [[x]]222; CHECK: fmadd [[y:s[0-9]+]], {{.*}}, [[x]]223; CHECK: str [[y]]224 225define void @f5(ptr nocapture readonly %p, ptr nocapture %q) #0 {226entry:227 %0 = load float, ptr %p, align 4228 %arrayidx1 = getelementptr inbounds float, ptr %p, i64 1229 %1 = load float, ptr %arrayidx1, align 4230 %arrayidx2 = getelementptr inbounds float, ptr %p, i64 2231 %2 = load float, ptr %arrayidx2, align 4232 %arrayidx3 = getelementptr inbounds float, ptr %p, i64 3233 %3 = load float, ptr %arrayidx3, align 4234 %arrayidx4 = getelementptr inbounds float, ptr %p, i64 4235 %4 = load float, ptr %arrayidx4, align 4236 %mul = fmul fast float %0, %1237 %add = fadd fast float %mul, %4238 %mul5 = fmul fast float %1, %2239 %add6 = fadd fast float %mul5, %add240 %mul7 = fmul fast float %1, %3241 %sub = fsub fast float %add6, %mul7242 %mul8 = fmul fast float %2, %3243 %add9 = fadd fast float %mul8, %sub244 %cmp = fcmp oeq float %3, 0.000000e+00245 br i1 %cmp, label %if.then, label %if.end246 247if.then: ; preds = %entry248 tail call void @g() #2249 br label %if.end250 251if.end: ; preds = %if.then, %entry252 store float %add9, ptr %q, align 4253 ret void254}255 256; Test that regmask clobbering stops a chain sequence.257 258; CHECK-LABEL: f6:259; CHECK-EVEN: fmadd [[x:d[0-9]*[02468]]]260; CHECK-ODD: fmadd [[x:d[0-9]*[13579]]]261; CHECK: fmadd [[x]]262; CHECK: fmsub [[x]]263; CHECK: fmadd d0, {{.*}}, [[x]]264; CHECK: bl hh265; CHECK: str d0266 267define void @f6(ptr nocapture readonly %p, ptr nocapture %q) #0 {268entry:269 %0 = load double, ptr %p, align 8270 %arrayidx1 = getelementptr inbounds double, ptr %p, i64 1271 %1 = load double, ptr %arrayidx1, align 8272 %arrayidx2 = getelementptr inbounds double, ptr %p, i64 2273 %2 = load double, ptr %arrayidx2, align 8274 %arrayidx3 = getelementptr inbounds double, ptr %p, i64 3275 %3 = load double, ptr %arrayidx3, align 8276 %arrayidx4 = getelementptr inbounds double, ptr %p, i64 4277 %4 = load double, ptr %arrayidx4, align 8278 %mul = fmul fast double %0, %1279 %add = fadd fast double %mul, %4280 %mul5 = fmul fast double %1, %2281 %add6 = fadd fast double %mul5, %add282 %mul7 = fmul fast double %1, %3283 %sub = fsub fast double %add6, %mul7284 %mul8 = fmul fast double %2, %3285 %add9 = fadd fast double %mul8, %sub286 %call = tail call double @hh(double %add9) #2287 store double %call, ptr %q, align 8288 ret void289}290 291declare double @hh(double) #1292 293; Check that we correctly deal with repeated operands.294; The following testcase creates:295; %d1 = FADDDrr killed %d0, %d0296; We'll get a crash if we naively look at the first operand, remove it297; from the substitution list then look at the second operand.298 299; CHECK: fmadd [[x:d[0-9]+]]300; CHECK: fadd d1, [[x]], [[x]]301 302define void @f7(ptr nocapture readonly %p, ptr nocapture %q) #0 {303entry:304 %0 = load double, ptr %p, align 8305 %arrayidx1 = getelementptr inbounds double, ptr %p, i64 1306 %1 = load double, ptr %arrayidx1, align 8307 %arrayidx2 = getelementptr inbounds double, ptr %p, i64 2308 %2 = load double, ptr %arrayidx2, align 8309 %arrayidx3 = getelementptr inbounds double, ptr %p, i64 3310 %3 = load double, ptr %arrayidx3, align 8311 %arrayidx4 = getelementptr inbounds double, ptr %p, i64 4312 %4 = load double, ptr %arrayidx4, align 8313 %mul = fmul fast double %0, %1314 %add = fadd fast double %mul, %4315 %mul5 = fmul fast double %1, %2316 %add6 = fadd fast double %mul5, %add317 %mul7 = fmul fast double %1, %3318 %sub = fsub fast double %add6, %mul7319 %mul8 = fmul fast double %2, %3320 %add9 = fadd fast double %mul8, %sub321 %add10 = fadd fast double %add9, %add9322 call void @hhh(double 0.0, double %add10)323 ret void324}325 326declare void @hhh(double, double)327 328attributes #0 = { nounwind "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "stack-protector-buffer-size"="8" "use-soft-float"="false" }329attributes #1 = { "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "stack-protector-buffer-size"="8" "use-soft-float"="false" }330attributes #2 = { nounwind }331 332