From 0648e42e5281341ea3bdf075ff653a64f8356450 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 7 Oct 2022 10:17:29 +0100 Subject: [PATCH] [NFC] Pre-commit tests for D135434. pipeliner-preserve-ties.mir demonstrates a current bug in which the output of the Modulo Software Pipelining pass has left off a tie between operands in the conditional `t2ADDri` instruction. It should look like this: %19:rgpr = t2ADDri %1, 1, 1 /* CC::ne */, $cpsr, $noreg, implicit %1(tied-def 0) in which the final input operand is tied to the output, because that's the input that will become the output value if the conditionalized add instruction does not execute, and hence, must necessarily be whatever was in the output register beforehand. In the input to the pipeliner, those `tied-def` specifications are present and correct. But when the pipeliner clones MachineInstrs, it loses them. pipeliner-inlineasm.mir does not demonstrate any bug: the output is already correct, because of compensation code in the machine pipeliner that applies only to INLINEASM instructions. But no test previously exercised that code, so I add one now before making changes in that area. --- llvm/test/CodeGen/Thumb2/pipeliner-inlineasm.mir | 212 +++++++++++++++ .../CodeGen/Thumb2/pipeliner-preserve-ties.mir | 296 +++++++++++++++++++++ 2 files changed, 508 insertions(+) create mode 100644 llvm/test/CodeGen/Thumb2/pipeliner-inlineasm.mir create mode 100644 llvm/test/CodeGen/Thumb2/pipeliner-preserve-ties.mir diff --git a/llvm/test/CodeGen/Thumb2/pipeliner-inlineasm.mir b/llvm/test/CodeGen/Thumb2/pipeliner-inlineasm.mir new file mode 100644 index 0000000..25f8be7 --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/pipeliner-inlineasm.mir @@ -0,0 +1,212 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=thumbv7m-none-eabi -mcpu=cortex-m7 -run-pass=pipeliner --pipeliner-force-issue-width=10 -o - %s | FileCheck %s --check-prefix=CHECK + +--- | + define hidden float @dot(float* nocapture noundef readonly %a, float* nocapture noundef readonly %b, i32 noundef %sz) local_unnamed_addr #0 { + entry: + %cmp8 = icmp sgt i32 %sz, 0 + br i1 %cmp8, label %for.body.preheader, label %for.end + + for.body.preheader: ; preds = %entry + %scevgep = getelementptr float, float* %b, i32 -1 + %scevgep4 = getelementptr float, float* %a, i32 -1 + br label %for.body + + for.body: ; preds = %for.body.preheader, %for.body + %lsr.iv5 = phi float* [ %scevgep4, %for.body.preheader ], [ %scevgep6, %for.body ] + %lsr.iv1 = phi float* [ %scevgep, %for.body.preheader ], [ %scevgep2, %for.body ] + %lsr.iv = phi i32 [ %sz, %for.body.preheader ], [ %lsr.iv.next, %for.body ] + %sum.010 = phi float [ %add, %for.body ], [ 0.000000e+00, %for.body.preheader ] + %scevgep7 = getelementptr float, float* %lsr.iv5, i32 1 + %0 = load float, float* %scevgep7, align 4 + %scevgep3 = getelementptr float, float* %lsr.iv1, i32 1 + %1 = load float, float* %scevgep3, align 4 + %mul = fmul fast float %1, %0 + %add = fadd fast float %mul, %sum.010 + %lsr.iv.next = add i32 %lsr.iv, -1 + %scevgep2 = getelementptr float, float* %lsr.iv1, i32 1 + %scevgep6 = getelementptr float, float* %lsr.iv5, i32 1 + %exitcond.not = icmp ne i32 %lsr.iv.next, 0 + br i1 %exitcond.not, label %for.body, label %for.end, !llvm.loop !0 + + for.end: ; preds = %for.body, %entry + %sum.0.lcssa = phi float [ 0.000000e+00, %entry ], [ %add, %for.body ] + ret float %sum.0.lcssa + } + + !0 = distinct !{!0, !1, !2, !3} + !1 = !{!"llvm.loop.mustprogress"} + !2 = !{!"llvm.loop.unroll.disable"} + !3 = !{!"llvm.loop.pipeline.initiationinterval", i32 3} + +... +--- +name: dot +alignment: 2 +tracksRegLiveness: true +registers: + - { id: 25, class: spr, preferred-register: '' } +constants: + - id: 0 + value: 'float 0.000000e+00' + alignment: 4 + isTargetSpecific: false +body: | + ; CHECK-LABEL: name: dot + ; CHECK: bb.0.entry: + ; CHECK-NEXT: successors: %bb.2(0x50000000), %bb.1(0x30000000) + ; CHECK-NEXT: liveins: $r0, $r1, $r2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gprnopc = COPY $r2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gprnopc = COPY $r1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gprnopc = COPY $r0 + ; CHECK-NEXT: t2CMPri [[COPY]], 1, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: t2Bcc %bb.2, 10 /* CC::ge */, $cpsr + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1: + ; CHECK-NEXT: successors: %bb.4(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[VLDRS:%[0-9]+]]:spr = VLDRS %const.0, 0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool) + ; CHECK-NEXT: t2B %bb.4, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.for.body.preheader: + ; CHECK-NEXT: successors: %bb.5(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[t2SUBri:%[0-9]+]]:rgpr = t2SUBri [[COPY1]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gprnopc = COPY [[t2SUBri]] + ; CHECK-NEXT: [[t2SUBri1:%[0-9]+]]:rgpr = t2SUBri [[COPY2]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[VLDRS1:%[0-9]+]]:spr = VLDRS %const.0, 0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool) + ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gprnopc = COPY [[t2SUBri1]] + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.5.for.body: + ; CHECK-NEXT: successors: %bb.6(0x40000000), %bb.9(0x40000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[t2ADDri:%[0-9]+]]:rgpr = t2ADDri [[COPY4]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[VLDRS2:%[0-9]+]]:spr = VLDRS [[COPY4]], 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.scevgep7) + ; CHECK-NEXT: [[t2ADDri1:%[0-9]+]]:rgpr = t2ADDri [[COPY3]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[VLDRS3:%[0-9]+]]:spr = VLDRS [[COPY3]], 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.scevgep3) + ; CHECK-NEXT: INLINEASM &nop, 0 /* attdialect */, 196618 /* regdef:SPR */, def %30, 2147483657 /* reguse tiedto:$0 */, [[VLDRS2]] + ; CHECK-NEXT: [[t2SUBri2:%[0-9]+]]:rgpr = t2SUBri [[COPY]], 1, 14 /* CC::al */, $noreg, def $cpsr + ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gprnopc = COPY [[t2SUBri2]] + ; CHECK-NEXT: [[COPY6:%[0-9]+]]:gprnopc = COPY [[t2ADDri1]] + ; CHECK-NEXT: [[COPY7:%[0-9]+]]:gprnopc = COPY [[t2ADDri]] + ; CHECK-NEXT: t2Bcc %bb.9, 0 /* CC::eq */, $cpsr + ; CHECK-NEXT: t2B %bb.6, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.6.for.body: + ; CHECK-NEXT: successors: %bb.7(0x80000000), %bb.8(0x00000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[VMULS:%[0-9]+]]:spr = nnan ninf nsz arcp contract afn reassoc VMULS [[VLDRS3]], %30, 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2ADDri2:%[0-9]+]]:rgpr = t2ADDri [[COPY7]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[VLDRS4:%[0-9]+]]:spr = VLDRS [[COPY7]], 1, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.scevgep7, align 4) + ; CHECK-NEXT: [[t2ADDri3:%[0-9]+]]:rgpr = t2ADDri [[COPY6]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[VLDRS5:%[0-9]+]]:spr = VLDRS [[COPY6]], 1, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.scevgep3, align 4) + ; CHECK-NEXT: INLINEASM &nop, 0 /* attdialect */, 196618 /* regdef:SPR */, def %40, 2147483657 /* reguse tiedto:$0 */, [[VLDRS4]] + ; CHECK-NEXT: [[t2SUBri3:%[0-9]+]]:rgpr = t2SUBri [[COPY5]], 1, 14 /* CC::al */, $noreg, def $cpsr + ; CHECK-NEXT: [[COPY8:%[0-9]+]]:gpr = COPY [[t2SUBri3]] + ; CHECK-NEXT: [[COPY9:%[0-9]+]]:gpr = COPY [[t2ADDri3]] + ; CHECK-NEXT: [[COPY10:%[0-9]+]]:gpr = COPY [[t2ADDri2]] + ; CHECK-NEXT: t2Bcc %bb.8, 0 /* CC::eq */, $cpsr + ; CHECK-NEXT: t2B %bb.7, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.7.for.body: + ; CHECK-NEXT: successors: %bb.8(0x04000000), %bb.7(0x7c000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[PHI:%[0-9]+]]:gprnopc = PHI [[COPY10]], %bb.6, %52, %bb.7 + ; CHECK-NEXT: [[PHI1:%[0-9]+]]:gprnopc = PHI [[COPY9]], %bb.6, %53, %bb.7 + ; CHECK-NEXT: [[PHI2:%[0-9]+]]:gprnopc = PHI [[COPY8]], %bb.6, %54, %bb.7 + ; CHECK-NEXT: [[PHI3:%[0-9]+]]:spr = PHI [[VLDRS1]], %bb.6, %51, %bb.7 + ; CHECK-NEXT: [[PHI4:%[0-9]+]]:spr = PHI [[VLDRS5]], %bb.6, %47, %bb.7 + ; CHECK-NEXT: [[PHI5:%[0-9]+]]:spr = PHI %40, %bb.6, %55, %bb.7 + ; CHECK-NEXT: [[PHI6:%[0-9]+]]:spr = PHI [[VMULS]], %bb.6, %45, %bb.7 + ; CHECK-NEXT: [[VMULS1:%[0-9]+]]:spr = nnan ninf nsz arcp contract afn reassoc VMULS [[PHI4]], [[PHI5]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2SUBri4:%[0-9]+]]:rgpr = t2SUBri [[PHI2]], 1, 14 /* CC::al */, $noreg, def $cpsr + ; CHECK-NEXT: [[VLDRS6:%[0-9]+]]:spr = VLDRS [[PHI1]], 1, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.scevgep3, align 4) + ; CHECK-NEXT: [[VLDRS7:%[0-9]+]]:spr = VLDRS [[PHI]], 1, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.scevgep7, align 4) + ; CHECK-NEXT: [[t2ADDri4:%[0-9]+]]:rgpr = t2ADDri [[PHI]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[t2ADDri5:%[0-9]+]]:rgpr = t2ADDri [[PHI1]], 4, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[VADDS:%[0-9]+]]:spr = nnan ninf nsz arcp contract afn reassoc VADDS [[PHI6]], [[PHI3]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[COPY11:%[0-9]+]]:gpr = COPY [[t2ADDri4]] + ; CHECK-NEXT: [[COPY12:%[0-9]+]]:gpr = COPY [[t2ADDri5]] + ; CHECK-NEXT: [[COPY13:%[0-9]+]]:gpr = COPY [[t2SUBri4]] + ; CHECK-NEXT: INLINEASM &nop, 0 /* attdialect */, 196618 /* regdef:SPR */, def %55, 2147483657 /* reguse tiedto:$0 */, [[VLDRS7]](tied-def 3) + ; CHECK-NEXT: t2Bcc %bb.8, 0 /* CC::eq */, $cpsr + ; CHECK-NEXT: t2B %bb.7, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.8: + ; CHECK-NEXT: successors: %bb.9(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[PHI7:%[0-9]+]]:spr = PHI [[VLDRS1]], %bb.6, [[VADDS]], %bb.7 + ; CHECK-NEXT: [[PHI8:%[0-9]+]]:spr = PHI [[VLDRS5]], %bb.6, [[VLDRS6]], %bb.7 + ; CHECK-NEXT: [[PHI9:%[0-9]+]]:spr = PHI %40, %bb.6, %55, %bb.7 + ; CHECK-NEXT: [[PHI10:%[0-9]+]]:spr = PHI [[VMULS]], %bb.6, [[VMULS1]], %bb.7 + ; CHECK-NEXT: [[VADDS1:%[0-9]+]]:spr = nnan ninf nsz arcp contract afn reassoc VADDS [[PHI10]], [[PHI7]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.9: + ; CHECK-NEXT: successors: %bb.4(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[PHI11:%[0-9]+]]:spr = PHI [[VLDRS1]], %bb.5, [[VADDS1]], %bb.8 + ; CHECK-NEXT: [[PHI12:%[0-9]+]]:spr = PHI [[VLDRS3]], %bb.5, [[PHI8]], %bb.8 + ; CHECK-NEXT: [[PHI13:%[0-9]+]]:spr = PHI %30, %bb.5, [[PHI9]], %bb.8 + ; CHECK-NEXT: [[VMULS2:%[0-9]+]]:spr = nnan ninf nsz arcp contract afn reassoc VMULS [[PHI12]], [[PHI13]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[VADDS2:%[0-9]+]]:spr = nnan ninf nsz arcp contract afn reassoc VADDS [[VMULS2]], [[PHI11]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: t2B %bb.4, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.4.for.end: + ; CHECK-NEXT: [[PHI14:%[0-9]+]]:spr = PHI [[VLDRS]], %bb.1, [[VADDS2]], %bb.9 + ; CHECK-NEXT: [[VMOVRS:%[0-9]+]]:gpr = VMOVRS [[PHI14]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: $r0 = COPY [[VMOVRS]] + ; CHECK-NEXT: tBX_RET 14 /* CC::al */, $noreg, implicit $r0 + bb.0.entry: + successors: %bb.1(0x50000000), %bb.4(0x30000000) + liveins: $r0, $r1, $r2 + + %13:gprnopc = COPY $r2 + %12:gprnopc = COPY $r1 + %11:gprnopc = COPY $r0 + t2CMPri %13, 1, 14 /* CC::al */, $noreg, implicit-def $cpsr + t2Bcc %bb.1, 10 /* CC::ge */, $cpsr + + bb.4: + successors: %bb.3(0x80000000) + + %14:spr = VLDRS %const.0, 0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool) + t2B %bb.3, 14 /* CC::al */, $noreg + + bb.1.for.body.preheader: + successors: %bb.2(0x80000000) + + %16:rgpr = t2SUBri %12, 4, 14 /* CC::al */, $noreg, $noreg + %0:gpr = COPY %16 + %17:rgpr = t2SUBri %11, 4, 14 /* CC::al */, $noreg, $noreg + %15:spr = VLDRS %const.0, 0, 14 /* CC::al */, $noreg :: (load (s32) from constant-pool) + %1:gpr = COPY %17 + + bb.2.for.body: + successors: %bb.3(0x04000000), %bb.2(0x7c000000) + + %2:gprnopc = PHI %1, %bb.1, %9, %bb.2 + %3:gprnopc = PHI %0, %bb.1, %8, %bb.2 + %4:gprnopc = PHI %13, %bb.1, %7, %bb.2 + %5:spr = PHI %15, %bb.1, %6, %bb.2 + %18:rgpr = t2ADDri %2, 4, 14 /* CC::al */, $noreg, $noreg + %19:spr = VLDRS %2, 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.scevgep7) + %20:rgpr = t2ADDri %3, 4, 14 /* CC::al */, $noreg, $noreg + %21:spr = VLDRS %3, 1, 14 /* CC::al */, $noreg :: (load (s32) from %ir.scevgep3) + INLINEASM &nop, 0 /* attdialect */, 196618 /* regdef:SPR */, def %25, 2147483657 /* reguse tiedto:$0 */, %19(tied-def 3) + %22:spr = nnan ninf nsz arcp contract afn reassoc VMULS killed %21, killed %25, 14 /* CC::al */, $noreg + %6:spr = nnan ninf nsz arcp contract afn reassoc VADDS killed %22, %5, 14 /* CC::al */, $noreg + %23:rgpr = t2SUBri %4, 1, 14 /* CC::al */, $noreg, def $cpsr + %7:gpr = COPY %23 + %8:gpr = COPY %20 + %9:gpr = COPY %18 + t2Bcc %bb.3, 0 /* CC::eq */, $cpsr + t2B %bb.2, 14 /* CC::al */, $noreg + + bb.3.for.end: + %10:spr = PHI %14, %bb.4, %6, %bb.2 + %24:gpr = VMOVRS %10, 14 /* CC::al */, $noreg + $r0 = COPY %24 + tBX_RET 14 /* CC::al */, $noreg, implicit $r0 + +... diff --git a/llvm/test/CodeGen/Thumb2/pipeliner-preserve-ties.mir b/llvm/test/CodeGen/Thumb2/pipeliner-preserve-ties.mir new file mode 100644 index 0000000..d656db2 --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/pipeliner-preserve-ties.mir @@ -0,0 +1,296 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=thumbv7-none-eabi -mcpu=cortex-m7 -O3 -run-pass=tbaa,pipeliner %s -o - | FileCheck %s + +--- | + ; ModuleID = 'test.ll' + source_filename = "test.ll" + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv7m-none-unknown-eabi" + + %struct.bar = type { i16, i16, i16, i16, i16, i16, i16, i16 } + + @bar = external local_unnamed_addr global [0 x %struct.bar], align 2 + + define i32 @foo() local_unnamed_addr #0 { + entry: + br label %do.body + + do.body: ; preds = %do.body, %entry + %lsr.iv = phi ptr [ %uglygep, %do.body ], [ getelementptr (i8, ptr @bar, i32 -16), %entry ] + %count.0 = phi i32 [ 0, %entry ], [ %count.4, %do.body ] + %uglygep1 = getelementptr i8, ptr %lsr.iv, i32 16 + %0 = load i16, ptr %uglygep1, align 2, !tbaa !0 + %conv = sext i16 %0 to i32 + %uglygep2 = getelementptr i8, ptr %uglygep1, i32 2 + %1 = load i16, ptr %uglygep2, align 2, !tbaa !5 + %conv2 = sext i16 %1 to i32 + %conv.frozen = freeze i32 %conv + %conv2.frozen = freeze i32 %conv2 + %div = sdiv i32 %conv.frozen, %conv2.frozen + %conv3 = trunc i32 %div to i16 + %2 = zext i16 %conv3 to i32 + %uglygep3 = getelementptr i8, ptr %uglygep1, i32 12 + %3 = trunc i32 %2 to i16 + store i16 %3, ptr %uglygep3, align 2, !tbaa !6 + %4 = mul i32 %div, %conv2.frozen + %rem.decomposed = sub i32 %conv.frozen, %4 + %conv8 = trunc i32 %rem.decomposed to i16 + %5 = zext i16 %conv8 to i32 + %uglygep4 = getelementptr i8, ptr %uglygep1, i32 14 + %6 = trunc i32 %5 to i16 + store i16 %6, ptr %uglygep4, align 2, !tbaa !7 + %uglygep5 = getelementptr i8, ptr %uglygep1, i32 4 + %7 = load i16, ptr %uglygep5, align 2, !tbaa !8 + %8 = zext i16 %7 to i32 + %cmp.not = icmp ne i32 %8, %2 + %inc = zext i1 %cmp.not to i32 + %spec.select = add nsw i32 %count.0, %inc + %uglygep6 = getelementptr i8, ptr %uglygep1, i32 6 + %9 = load i16, ptr %uglygep6, align 2, !tbaa !9 + %10 = zext i16 %9 to i32 + %cmp16.not = icmp ne i32 %10, %5 + %inc19 = zext i1 %cmp16.not to i32 + %count.2 = add nsw i32 %spec.select, %inc19 + %uglygep7 = getelementptr i8, ptr %uglygep1, i32 8 + %11 = load i16, ptr %uglygep7, align 2, !tbaa !10 + %12 = zext i16 %11 to i32 + %cmp24.not = icmp ne i32 %12, %2 + %inc27 = zext i1 %cmp24.not to i32 + %count.3 = add nsw i32 %count.2, %inc27 + %uglygep8 = getelementptr i8, ptr %uglygep1, i32 10 + %13 = load i16, ptr %uglygep8, align 2, !tbaa !11 + %14 = zext i16 %13 to i32 + %cmp32.not = icmp ne i32 %14, %5 + %inc35 = zext i1 %cmp32.not to i32 + %count.4 = add nsw i32 %count.3, %inc35 + %uglygep9 = getelementptr i8, ptr %uglygep1, i32 18 + %15 = load i16, ptr %uglygep9, align 2, !tbaa !5 + %tobool.not = icmp eq i16 %15, 0 + %uglygep = getelementptr i8, ptr %lsr.iv, i32 16 + br i1 %tobool.not, label %do.end, label %do.body + + do.end: ; preds = %do.body + ret i32 %count.4 + } + + attributes #0 = { "target-cpu"="cortex-m7" } + + !0 = !{!1, !2, i64 0} + !1 = !{!"bar", !2, i64 0, !2, i64 2, !2, i64 4, !2, i64 6, !2, i64 8, !2, i64 10, !2, i64 12, !2, i64 14} + !2 = !{!"short", !3, i64 0} + !3 = !{!"omnipotent char", !4, i64 0} + !4 = !{!"Simple C/C++ TBAA"} + !5 = !{!1, !2, i64 2} + !6 = !{!1, !2, i64 12} + !7 = !{!1, !2, i64 14} + !8 = !{!1, !2, i64 4} + !9 = !{!1, !2, i64 6} + !10 = !{!1, !2, i64 8} + !11 = !{!1, !2, i64 10} + +... +--- +name: foo +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +callsEHReturn: false +callsUnwindInit: false +hasEHCatchret: false +hasEHScopes: false +hasEHFunclets: false +failsVerification: false +tracksDebugUserValues: false +registers: + - { id: 0, class: gpr, preferred-register: '' } + - { id: 1, class: rgpr, preferred-register: '' } + - { id: 2, class: gpr, preferred-register: '' } + - { id: 3, class: gpr, preferred-register: '' } + - { id: 4, class: gpr, preferred-register: '' } + - { id: 5, class: gpr, preferred-register: '' } + - { id: 6, class: rgpr, preferred-register: '' } + - { id: 7, class: rgpr, preferred-register: '' } + - { id: 8, class: rgpr, preferred-register: '' } + - { id: 9, class: rgpr, preferred-register: '' } + - { id: 10, class: rgpr, preferred-register: '' } + - { id: 11, class: rgpr, preferred-register: '' } + - { id: 12, class: rgpr, preferred-register: '' } + - { id: 13, class: rgpr, preferred-register: '' } + - { id: 14, class: rgpr, preferred-register: '' } + - { id: 15, class: rgpr, preferred-register: '' } + - { id: 16, class: rgpr, preferred-register: '' } + - { id: 17, class: gprnopc, preferred-register: '' } + - { id: 18, class: rgpr, preferred-register: '' } + - { id: 19, class: rgpr, preferred-register: '' } + - { id: 20, class: gprnopc, preferred-register: '' } + - { id: 21, class: rgpr, preferred-register: '' } + - { id: 22, class: rgpr, preferred-register: '' } + - { id: 23, class: gprnopc, preferred-register: '' } + - { id: 24, class: rgpr, preferred-register: '' } + - { id: 25, class: rgpr, preferred-register: '' } + - { id: 26, class: gprnopc, preferred-register: '' } + - { id: 27, class: rgpr, preferred-register: '' } + - { id: 28, class: rgpr, preferred-register: '' } + - { id: 29, class: gprnopc, preferred-register: '' } +liveins: [] +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: false + hasCalls: false + stackProtector: '' + functionContext: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + hasTailCall: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +callSites: [] +debugValueSubstitutions: [] +constants: [] +machineFunctionInfo: {} +body: | + ; CHECK-LABEL: name: foo + ; CHECK: bb.0.entry: + ; CHECK-NEXT: successors: %bb.3(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[t2MOVi32imm:%[0-9]+]]:rgpr = t2MOVi32imm @bar + ; CHECK-NEXT: [[t2SUBri:%[0-9]+]]:rgpr = t2SUBri [[t2MOVi32imm]], 16, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[t2MOVi:%[0-9]+]]:rgpr = t2MOVi 0, 14 /* CC::al */, $noreg, $noreg + ; CHECK-NEXT: [[COPY:%[0-9]+]]:rgpr = COPY [[t2MOVi]] + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY [[t2SUBri]] + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.3.do.body: + ; CHECK-NEXT: successors: %bb.4(0x80000000), %bb.5(0x00000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[t2LDRSH_PRE:%[0-9]+]]:rgpr, [[t2LDRSH_PRE1:%[0-9]+]]:gpr = t2LDRSH_PRE [[COPY1]], 16, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep1, !tbaa !0) + ; CHECK-NEXT: [[t2LDRSHi12_:%[0-9]+]]:rgpr = t2LDRSHi12 [[t2LDRSH_PRE1]], 2, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep2, !tbaa !5) + ; CHECK-NEXT: [[t2SDIV:%[0-9]+]]:rgpr = t2SDIV [[t2LDRSH_PRE]], [[t2LDRSHi12_]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2UXTH:%[0-9]+]]:rgpr = t2UXTH [[t2SDIV]], 0, 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2MLS:%[0-9]+]]:rgpr = t2MLS [[t2SDIV]], [[t2LDRSHi12_]], [[t2LDRSH_PRE]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2UXTH1:%[0-9]+]]:rgpr = t2UXTH [[t2MLS]], 0, 14 /* CC::al */, $noreg + ; CHECK-NEXT: t2STRHi12 [[t2MLS]], [[t2LDRSH_PRE1]], 14, 14 /* CC::al */, $noreg :: (store (s16) into %ir.uglygep4, !tbaa !7) + ; CHECK-NEXT: [[t2LDRHi12_:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE1]], 4, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep5, !tbaa !8) + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_]], [[t2UXTH]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri:%[0-9]+]]:rgpr = t2ADDri [[COPY]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[COPY]] + ; CHECK-NEXT: [[t2LDRHi12_1:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE1]], 6, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep6, !tbaa !9) + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_1]], [[t2UXTH1]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri1:%[0-9]+]]:rgpr = t2ADDri [[t2ADDri]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[t2ADDri]] + ; CHECK-NEXT: [[t2LDRHi12_2:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE1]], 8, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep7, !tbaa !10) + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_2]], [[t2UXTH]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri2:%[0-9]+]]:rgpr = t2ADDri [[t2ADDri1]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[t2ADDri1]] + ; CHECK-NEXT: [[t2LDRHi12_3:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE1]], 10, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep8, !tbaa !11) + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_3]], [[t2UXTH1]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri3:%[0-9]+]]:rgpr = t2ADDri [[t2ADDri2]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[t2ADDri2]] + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY [[t2ADDri3]] + ; CHECK-NEXT: [[t2LDRHi12_4:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE1]], 18, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep9, !tbaa !5) + ; CHECK-NEXT: t2CMPri [[t2LDRHi12_4]], 0, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: t2Bcc %bb.5, 0 /* CC::eq */, $cpsr + ; CHECK-NEXT: t2B %bb.4, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.4.do.body: + ; CHECK-NEXT: successors: %bb.5(0x04000000), %bb.4(0x7c000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr = PHI [[t2LDRSH_PRE1]], %bb.3, %48, %bb.4 + ; CHECK-NEXT: [[PHI1:%[0-9]+]]:rgpr = PHI [[COPY2]], %bb.3, %63, %bb.4 + ; CHECK-NEXT: [[PHI2:%[0-9]+]]:gpr = PHI [[t2LDRSH_PRE1]], %bb.3, %48, %bb.4 + ; CHECK-NEXT: [[PHI3:%[0-9]+]]:rgpr = PHI [[t2SDIV]], %bb.3, %53, %bb.4 + ; CHECK-NEXT: t2STRHi12 [[PHI3]], [[PHI2]], 12, 14 /* CC::al */, $noreg :: (store (s16) into %ir.uglygep3, !tbaa !6) + ; CHECK-NEXT: [[t2LDRSH_PRE2:%[0-9]+]]:rgpr, [[t2LDRSH_PRE3:%[0-9]+]]:gpr = t2LDRSH_PRE [[PHI]], 16, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep1, align 2, !tbaa !0) + ; CHECK-NEXT: [[t2LDRSHi12_1:%[0-9]+]]:rgpr = t2LDRSHi12 [[t2LDRSH_PRE3]], 2, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep2, align 2, !tbaa !5) + ; CHECK-NEXT: [[t2LDRHi12_5:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE3]], 18, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep9, align 2, !tbaa !5) + ; CHECK-NEXT: [[t2LDRHi12_6:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE3]], 8, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep7, align 2, !tbaa !10) + ; CHECK-NEXT: [[t2LDRHi12_7:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE3]], 10, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep8, align 2, !tbaa !11) + ; CHECK-NEXT: [[t2SDIV1:%[0-9]+]]:rgpr = t2SDIV [[t2LDRSH_PRE2]], [[t2LDRSHi12_1]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2LDRHi12_8:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE3]], 4, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep5, align 2, !tbaa !8) + ; CHECK-NEXT: [[t2MLS1:%[0-9]+]]:rgpr = t2MLS [[t2SDIV1]], [[t2LDRSHi12_1]], [[t2LDRSH_PRE2]], 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2UXTH2:%[0-9]+]]:rgpr = t2UXTH [[t2SDIV1]], 0, 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2LDRHi12_9:%[0-9]+]]:gprnopc = t2LDRHi12 [[t2LDRSH_PRE3]], 6, 14 /* CC::al */, $noreg :: (load unknown-size from %ir.uglygep6, align 2, !tbaa !9) + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_8]], [[t2UXTH2]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2UXTH3:%[0-9]+]]:rgpr = t2UXTH [[t2MLS1]], 0, 14 /* CC::al */, $noreg + ; CHECK-NEXT: [[t2ADDri4:%[0-9]+]]:rgpr = t2ADDri [[PHI1]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[PHI1]] + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_9]], [[t2UXTH3]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri5:%[0-9]+]]:rgpr = t2ADDri [[t2ADDri4]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[t2ADDri4]] + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_6]], [[t2UXTH2]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri6:%[0-9]+]]:rgpr = t2ADDri [[t2ADDri5]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[t2ADDri5]] + ; CHECK-NEXT: t2CMPrr [[t2LDRHi12_7]], [[t2UXTH3]], 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[t2ADDri7:%[0-9]+]]:rgpr = t2ADDri [[t2ADDri6]], 1, 1 /* CC::ne */, $cpsr, $noreg, implicit [[t2ADDri6]] + ; CHECK-NEXT: t2CMPri [[t2LDRHi12_5]], 0, 14 /* CC::al */, $noreg, implicit-def $cpsr + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY [[t2ADDri7]] + ; CHECK-NEXT: t2STRHi12 [[t2MLS1]], [[t2LDRSH_PRE3]], 14, 14 /* CC::al */, $noreg :: (store unknown-size into %ir.uglygep4, align 2, !tbaa !7) + ; CHECK-NEXT: t2Bcc %bb.4, 1 /* CC::ne */, $cpsr + ; CHECK-NEXT: t2B %bb.5, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.5: + ; CHECK-NEXT: successors: %bb.2(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[PHI4:%[0-9]+]]:gpr = PHI [[t2LDRSH_PRE1]], %bb.3, [[t2LDRSH_PRE3]], %bb.4 + ; CHECK-NEXT: [[PHI5:%[0-9]+]]:rgpr = PHI [[t2SDIV]], %bb.3, [[t2SDIV1]], %bb.4 + ; CHECK-NEXT: [[PHI6:%[0-9]+]]:gpr = PHI [[COPY2]], %bb.3, [[COPY3]], %bb.4 + ; CHECK-NEXT: t2STRHi12 [[PHI5]], [[PHI4]], 12, 14 /* CC::al */, $noreg :: (store unknown-size into %ir.uglygep3, align 2, !tbaa !6) + ; CHECK-NEXT: t2B %bb.2, 14 /* CC::al */, $noreg + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2.do.end: + ; CHECK-NEXT: $r0 = COPY [[PHI6]] + ; CHECK-NEXT: tBX_RET 14 /* CC::al */, $noreg, implicit $r0 + bb.0.entry: + successors: %bb.1(0x80000000) + + %6:rgpr = t2MOVi32imm @bar + %7:rgpr = t2SUBri killed %6, 16, 14 /* CC::al */, $noreg, $noreg + %8:rgpr = t2MOVi 0, 14 /* CC::al */, $noreg, $noreg + %5:gpr = COPY %8 + %4:gpr = COPY %7 + + bb.1.do.body: + successors: %bb.2(0x04000000), %bb.1(0x7c000000) + + %0:gpr = PHI %4, %bb.0, %3, %bb.1 + %1:rgpr = PHI %5, %bb.0, %2, %bb.1 + %9:rgpr, %3:gpr = t2LDRSH_PRE %0, 16, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep1, !tbaa !0) + %10:rgpr = t2LDRSHi12 %3, 2, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep2, !tbaa !5) + %13:rgpr = t2SDIV %9, %10, 14 /* CC::al */, $noreg + %14:rgpr = t2UXTH %13, 0, 14 /* CC::al */, $noreg + t2STRHi12 %13, %3, 12, 14 /* CC::al */, $noreg :: (store (s16) into %ir.uglygep3, !tbaa !6) + %15:rgpr = t2MLS %13, %10, %9, 14 /* CC::al */, $noreg + %16:rgpr = t2UXTH %15, 0, 14 /* CC::al */, $noreg + t2STRHi12 %15, %3, 14, 14 /* CC::al */, $noreg :: (store (s16) into %ir.uglygep4, !tbaa !7) + %17:gprnopc = t2LDRHi12 %3, 4, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep5, !tbaa !8) + t2CMPrr killed %17, %14, 14 /* CC::al */, $noreg, implicit-def $cpsr + %19:rgpr = t2ADDri %1, 1, 1 /* CC::ne */, $cpsr, $noreg, implicit %1(tied-def 0) + %20:gprnopc = t2LDRHi12 %3, 6, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep6, !tbaa !9) + t2CMPrr killed %20, %16, 14 /* CC::al */, $noreg, implicit-def $cpsr + %22:rgpr = t2ADDri %19, 1, 1 /* CC::ne */, $cpsr, $noreg, implicit %19(tied-def 0) + %23:gprnopc = t2LDRHi12 %3, 8, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep7, !tbaa !10) + t2CMPrr killed %23, %14, 14 /* CC::al */, $noreg, implicit-def $cpsr + %25:rgpr = t2ADDri %22, 1, 1 /* CC::ne */, $cpsr, $noreg, implicit %22(tied-def 0) + %26:gprnopc = t2LDRHi12 %3, 10, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep8, !tbaa !11) + t2CMPrr killed %26, %16, 14 /* CC::al */, $noreg, implicit-def $cpsr + %28:rgpr = t2ADDri %25, 1, 1 /* CC::ne */, $cpsr, $noreg, implicit %25(tied-def 0) + %2:gpr = COPY %28 + %29:gprnopc = t2LDRHi12 %3, 18, 14 /* CC::al */, $noreg :: (load (s16) from %ir.uglygep9, !tbaa !5) + t2CMPri killed %29, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr + t2Bcc %bb.1, 1 /* CC::ne */, $cpsr + t2B %bb.2, 14 /* CC::al */, $noreg + + bb.2.do.end: + $r0 = COPY %2 + tBX_RET 14 /* CC::al */, $noreg, implicit $r0 + +... -- 2.7.4