diff options
Diffstat (limited to 'llvm/test/CodeGen')
14 files changed, 599 insertions, 261 deletions
diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cond-mov.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cond-mov.mir index 1efe18e129c..b17965cd335 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cond-mov.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/cond-mov.mir @@ -4,6 +4,9 @@ # CHECK: $lr = t2LEUpdate renamable $lr, %bb.1 --- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + define i32 @do_copy(i32 %n, i32* nocapture %p, i32* nocapture readonly %q) { entry: %scevgep = getelementptr i32, i32* %q, i32 -1 @@ -15,10 +18,10 @@ %lsr.iv4 = phi i32* [ %scevgep5, %while.body ], [ %scevgep3, %entry ] %lsr.iv = phi i32* [ %scevgep1, %while.body ], [ %scevgep, %entry ] %0 = phi i32 [ %n, %entry ], [ %2, %while.body ] - %scevgep7 = getelementptr i32, i32* %lsr.iv, i32 1 - %scevgep4 = getelementptr i32, i32* %lsr.iv4, i32 1 - %1 = load i32, i32* %scevgep7, align 4 - store i32 %1, i32* %scevgep4, align 4 + %scevgep6 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep2 = getelementptr i32, i32* %lsr.iv4, i32 1 + %1 = load i32, i32* %scevgep6, align 4 + store i32 %1, i32* %scevgep2, align 4 %scevgep1 = getelementptr i32, i32* %lsr.iv, i32 1 %scevgep5 = getelementptr i32, i32* %lsr.iv4, i32 1 %2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) @@ -44,7 +47,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -84,6 +87,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.1(0x80000000) + liveins: $r0, $r1, $r2, $r7, $lr frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 8 @@ -96,9 +100,10 @@ body: | bb.1.while.body: successors: %bb.1(0x7c000000), %bb.2(0x04000000) + liveins: $lr, $r0, $r1 - renamable $r2, renamable $r1 = t2LDR_PRE killed renamable $r1, 4, 14, $noreg :: (load 4 from %ir.scevgep7) - early-clobber renamable $r0 = t2STR_PRE killed renamable $r2, killed renamable $r0, 4, 14, $noreg :: (store 4 into %ir.scevgep4) + renamable $r2, renamable $r1 = t2LDR_PRE killed renamable $r1, 4, 14, $noreg :: (load 4 from %ir.scevgep6) + early-clobber renamable $r0 = t2STR_PRE killed renamable $r2, killed renamable $r0, 4, 14, $noreg :: (store 4 into %ir.scevgep2) renamable $lr = t2LoopDec killed renamable $lr, 1 t2LoopEnd renamable $lr, %bb.1, implicit-def dead $cpsr tB %bb.2, 14, $noreg @@ -108,4 +113,3 @@ body: | tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 ... - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir index 2b12ec14901..82c533b8bdf 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/end-positive-offset.mir @@ -9,7 +9,10 @@ # CHECK: bb.2.for.cond.cleanup: # CHECK: bb.3.for.header: ---- | +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + define void @size_limit(i32* nocapture %a, i32* nocapture readonly %b, i32* nocapture readonly %c, i32 %N) { entry: call void @llvm.set.loop.iterations.i32(i32 %N) @@ -45,9 +48,11 @@ } ; Function Attrs: nounwind - declare i32 @llvm.arm.space(i32 immarg, i32) #0 + declare i32 @llvm.arm.space(i32 immarg, i32) #0 + ; Function Attrs: noduplicate nounwind - declare void @llvm.set.loop.iterations.i32(i32) #1 + declare void @llvm.set.loop.iterations.i32(i32) #1 + ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #1 @@ -63,7 +68,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -128,6 +133,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.3(0x80000000) + liveins: $r0, $r1, $r2, $r3, $r7, $lr frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 8 @@ -184,5 +190,3 @@ body: | tB %bb.1, 14, $noreg ... - - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mov-after-dls.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mov-after-dls.mir new file mode 100644 index 00000000000..47f933fdebd --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/mov-after-dls.mir @@ -0,0 +1,115 @@ +# RUN: llc -mtriple=thumbv8.1m.main -run-pass=arm-low-overhead-loops %s -verify-machineinstrs -o - | FileCheck %s +# CHECK: $lr = t2DLS $r0 +# CHECK-NOT: $lr = tMOVr $r0 +# CHECK: $lr = t2LEUpdate renamable $lr, %bb.1 + +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + + define i32 @do_copy(i32 %n, i32* nocapture %p, i32* nocapture readonly %q) { + entry: + %scevgep = getelementptr i32, i32* %q, i32 -1 + %scevgep3 = getelementptr i32, i32* %p, i32 -1 + call void @llvm.set.loop.iterations.i32(i32 %n) + br label %while.body + + while.body: ; preds = %while.body, %entry + %lsr.iv4 = phi i32* [ %scevgep5, %while.body ], [ %scevgep3, %entry ] + %lsr.iv = phi i32* [ %scevgep1, %while.body ], [ %scevgep, %entry ] + %0 = phi i32 [ %n, %entry ], [ %2, %while.body ] + %scevgep6 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep2 = getelementptr i32, i32* %lsr.iv4, i32 1 + %1 = load i32, i32* %scevgep6, align 4 + store i32 %1, i32* %scevgep2, align 4 + %scevgep1 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep5 = getelementptr i32, i32* %lsr.iv4, i32 1 + %2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) + %3 = icmp ne i32 %2, 0 + br i1 %3, label %while.body, label %while.end + + while.end: ; preds = %while.body + ret i32 0 + } + + declare void @llvm.set.loop.iterations.i32(i32) #0 + declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #0 + + attributes #0 = { noduplicate nounwind } + attributes #1 = { nounwind } + +... +--- +name: do_copy +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$r0', virtual-reg: '' } + - { reg: '$r1', virtual-reg: '' } + - { reg: '$r2', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 8 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0.entry: + successors: %bb.1(0x80000000) + liveins: $r0, $r1, $r2, $r7, $lr + + frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 + frame-setup CFI_INSTRUCTION offset $lr, -4 + frame-setup CFI_INSTRUCTION offset $r7, -8 + t2DoLoopStart $r0 + $lr = tMOVr killed $r0, 14, $noreg + renamable $r0, dead $cpsr = tSUBi3 killed renamable $r1, 4, 14, $noreg + renamable $r1, dead $cpsr = tSUBi3 killed renamable $r2, 4, 14, $noreg + + bb.1.while.body: + successors: %bb.1(0x7c000000), %bb.2(0x04000000) + liveins: $lr, $r0, $r1 + + renamable $r2, renamable $r1 = t2LDR_PRE killed renamable $r1, 4, 14, $noreg :: (load 4 from %ir.scevgep6) + early-clobber renamable $r0 = t2STR_PRE killed renamable $r2, killed renamable $r0, 4, 14, $noreg :: (store 4 into %ir.scevgep2) + renamable $lr = t2LoopDec killed renamable $lr, 1 + t2LoopEnd renamable $lr, %bb.1, implicit-def dead $cpsr + tB %bb.2, 14, $noreg + + bb.2.while.end: + $r0, dead $cpsr = tMOVi8 0, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 + +... diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-call.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-call.mir index 3ea75a295f6..e0434c4e050 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-call.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-call.mir @@ -5,8 +5,6 @@ # CHECK-NOT: t2LEUpdate --- | - ; ModuleID = '/home/sampar01/src/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-call.ll' - source_filename = "/home/sampar01/src/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-call.ll" target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv8.1m.main" @@ -35,15 +33,9 @@ declare i32 @bar(...) local_unnamed_addr #0 - ; Function Attrs: noduplicate nounwind declare void @llvm.set.loop.iterations.i32(i32) #1 - - ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #1 - ; Function Attrs: nounwind - declare void @llvm.stackprotector(i8*, i8**) #2 - attributes #0 = { "target-features"="+mve.fp" } attributes #1 = { noduplicate nounwind } attributes #2 = { nounwind } @@ -57,7 +49,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -101,6 +93,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.4(0x30000000), %bb.1(0x50000000) + liveins: $r0, $r4, $r5, $r7, $lr frame-setup tPUSH 14, $noreg, killed $r4, killed $r5, killed $r7, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 16 @@ -112,6 +105,7 @@ body: | bb.1.while.body.preheader: successors: %bb.2(0x80000000) + liveins: $r0 $lr = tMOVr $r0, 14, $noreg renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg @@ -119,6 +113,7 @@ body: | bb.2.while.body: successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r4 $r5 = tMOVr killed $lr, 14, $noreg tBL 14, $noreg, @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $r0 @@ -129,6 +124,8 @@ body: | tB %bb.3, 14, $noreg bb.3.while.end: + liveins: $r4 + $r0 = tMOVr killed $r4, 14, $noreg tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 @@ -138,4 +135,3 @@ body: | tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 ... - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-read.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-read.mir index b69d35859a7..fc270579740 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-read.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-read.mir @@ -4,7 +4,10 @@ # CHECK-NOT: t2DLS # CHECK-NOT: t2LEUpdate ---- | +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + define i32 @mov_between_dec_end(i32 %n) #0 { entry: %cmp6 = icmp eq i32 %n, 0 @@ -15,7 +18,6 @@ br label %while.body while.body: ; preds = %while.body, %while.body.preheader - %res.07 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] %0 = phi i32 [ %n, %while.body.preheader ], [ %1, %while.body ] %1 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) %add = add i32 %1, 0 @@ -27,10 +29,7 @@ ret i32 %res.0.lcssa } - ; Function Attrs: noduplicate nounwind declare void @llvm.set.loop.iterations.i32(i32) #1 - - ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #1 attributes #0 = { "target-features"="+mve.fp" } @@ -46,7 +45,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -56,11 +55,11 @@ frameInfo: isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false - stackSize: 16 + stackSize: 8 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: true - hasCalls: true + adjustsStack: false + hasCalls: false stackProtector: '' maxCallFrameSize: 0 cvBytesOfCalleeSavedRegisters: 0 @@ -78,51 +77,46 @@ stack: - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 2, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r5', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 3, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r4', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } callSites: [] constants: [] machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.4(0x30000000), %bb.1(0x50000000) + liveins: $r0, $r7, $lr - frame-setup tPUSH 14, $noreg, killed $r4, killed $r5, killed $r7, killed $lr, implicit-def $sp, implicit $sp - frame-setup CFI_INSTRUCTION def_cfa_offset 16 + frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 frame-setup CFI_INSTRUCTION offset $lr, -4 frame-setup CFI_INSTRUCTION offset $r7, -8 - frame-setup CFI_INSTRUCTION offset $r5, -12 - frame-setup CFI_INSTRUCTION offset $r4, -16 tCBZ $r0, %bb.4 bb.1.while.body.preheader: successors: %bb.2(0x80000000) + liveins: $r0 $lr = tMOVr $r0, 14, $noreg - renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg t2DoLoopStart killed $r0 bb.2.while.body: successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r4 - renamable $r4 = nsw tADDhirr killed renamable $r4, killed renamable $r0, 14, $noreg + renamable $r4 = nsw tADDhirr killed renamable $r4, killed renamable $r4, 14, $noreg renamable $lr = t2LoopDec killed renamable $lr, 1 renamable $r4 = tMOVr $lr, 14, $noreg t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr tB %bb.3, 14, $noreg bb.3.while.end: - $r0 = tMOVr killed $r4, 14, $noreg - tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 + liveins: $lr + + $r0 = tMOVr killed $lr, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 bb.4: - renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg - $r0 = tMOVr killed $r4, 14, $noreg - tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 + renamable $lr = t2MOVi 0, 14, $noreg, $noreg + $r0 = tMOVr killed $lr, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 ... - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-spill.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-spill.mir deleted file mode 100644 index 97ac75de497..00000000000 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-spill.mir +++ /dev/null @@ -1,136 +0,0 @@ -# RUN: llc -mtriple=thumbv8.1m.main %s -run-pass=arm-low-overhead-loops --verify-machineinstrs -o - | FileCheck %s - -# CHECK: while.body: -# CHECK-NOT: t2DLS -# CHECK-NOT: t2LEUpdate - ---- | - define i32 @skip_spill(i32 %n) #0 { - entry: - %cmp6 = icmp eq i32 %n, 0 - br i1 %cmp6, label %while.end, label %while.body.preheader - - while.body.preheader: ; preds = %entry - call void @llvm.set.loop.iterations.i32(i32 %n) - br label %while.body - - while.body: ; preds = %while.body, %while.body.preheader - %res.07 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] - %0 = phi i32 [ %n, %while.body.preheader ], [ %1, %while.body ] - %call = tail call i32 bitcast (i32 (...)* @bar to i32 ()*)() - %add = add nsw i32 %call, %res.07 - %1 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) - %2 = icmp ne i32 %1, 0 - br i1 %2, label %while.body, label %while.end - - while.end: ; preds = %while.body, %entry - %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.body ] - ret i32 %res.0.lcssa - } - - declare i32 @bar(...) local_unnamed_addr #0 - - ; Function Attrs: noduplicate nounwind - declare void @llvm.set.loop.iterations.i32(i32) #1 - - ; Function Attrs: noduplicate nounwind - declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #1 - - ; Function Attrs: nounwind - declare void @llvm.stackprotector(i8*, i8**) #2 - - attributes #0 = { "target-features"="+mve.fp" } - attributes #1 = { noduplicate nounwind } - attributes #2 = { nounwind } - -... ---- -name: skip_spill -alignment: 2 -exposesReturnsTwice: false -legalized: false -regBankSelected: false -selected: false -failedISel: false -tracksRegLiveness: false -hasWinCFI: false -registers: [] -liveins: - - { reg: '$r0', virtual-reg: '' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 16 - offsetAdjustment: 0 - maxAlignment: 4 - adjustsStack: true - hasCalls: true - stackProtector: '' - maxCallFrameSize: 0 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: - - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 2, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r5', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 3, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r4', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } -callSites: [] -constants: [] -machineFunctionInfo: {} -body: | - bb.0.entry: - successors: %bb.4(0x30000000), %bb.1(0x50000000) - - frame-setup tPUSH 14, $noreg, killed $r4, killed $r5, killed $r7, killed $lr, implicit-def $sp, implicit $sp - frame-setup CFI_INSTRUCTION def_cfa_offset 16 - frame-setup CFI_INSTRUCTION offset $lr, -4 - frame-setup CFI_INSTRUCTION offset $r7, -8 - frame-setup CFI_INSTRUCTION offset $r5, -12 - frame-setup CFI_INSTRUCTION offset $r4, -16 - tCBZ $r0, %bb.4 - - bb.1.while.body.preheader: - successors: %bb.2(0x80000000) - - $lr = tMOVr $r0, 14, $noreg - renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg - t2DoLoopStart killed $r0 - - bb.2.while.body: - successors: %bb.2(0x7c000000), %bb.3(0x04000000) - - $r5 = tMOVr killed $lr, 14, $noreg - tBL 14, $noreg, @bar, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $r0 - $lr = tMOVr killed $r5, 14, $noreg - renamable $r4 = nsw tADDhirr killed renamable $r4, killed renamable $r0, 14, $noreg - renamable $lr = t2LoopDec killed renamable $lr, 1 - t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr - tB %bb.3, 14, $noreg - - bb.3.while.end: - $r0 = tMOVr killed $r4, 14, $noreg - tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 - - bb.4: - renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg - $r0 = tMOVr killed $r4, 14, $noreg - tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 - -... - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-write.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-write.mir index 2d31c8ad63b..ca3a1122d98 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-write.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-after-write.mir @@ -4,7 +4,10 @@ # CHECK-NOT: t2DLS # CHECK-NOT: t2LEUpdate ---- | +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + define i32 @mov_between_dec_end(i32 %n) #0 { entry: %cmp6 = icmp eq i32 %n, 0 @@ -15,7 +18,6 @@ br label %while.body while.body: ; preds = %while.body, %while.body.preheader - %res.07 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ] %0 = phi i32 [ %n, %while.body.preheader ], [ %1, %while.body ] %1 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) %add = add i32 %1, 2 @@ -33,6 +35,9 @@ ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #1 + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #2 + attributes #0 = { "target-features"="+mve.fp" } attributes #1 = { noduplicate nounwind } attributes #2 = { nounwind } @@ -46,7 +51,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -56,11 +61,11 @@ frameInfo: isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false - stackSize: 16 + stackSize: 8 offsetAdjustment: 0 maxAlignment: 4 - adjustsStack: true - hasCalls: true + adjustsStack: false + hasCalls: false stackProtector: '' maxCallFrameSize: 0 cvBytesOfCalleeSavedRegisters: 0 @@ -78,51 +83,45 @@ stack: - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 2, name: '', type: spill-slot, offset: -12, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r5', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } - - { id: 3, name: '', type: spill-slot, offset: -16, size: 4, alignment: 4, - stack-id: default, callee-saved-register: '$r4', callee-saved-restored: true, - debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } callSites: [] constants: [] machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.4(0x30000000), %bb.1(0x50000000) + liveins: $r0, $r7, $lr - frame-setup tPUSH 14, $noreg, killed $r4, killed $r5, killed $r7, killed $lr, implicit-def $sp, implicit $sp - frame-setup CFI_INSTRUCTION def_cfa_offset 16 + frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 frame-setup CFI_INSTRUCTION offset $lr, -4 frame-setup CFI_INSTRUCTION offset $r7, -8 - frame-setup CFI_INSTRUCTION offset $r5, -12 - frame-setup CFI_INSTRUCTION offset $r4, -16 tCBZ $r0, %bb.4 bb.1.while.body.preheader: successors: %bb.2(0x80000000) + liveins: $r0 $lr = tMOVr $r0, 14, $noreg - renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg t2DoLoopStart killed $r0 bb.2.while.body: successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr $r4 = tMOVr $lr, 14, $noreg renamable $lr = t2LoopDec killed renamable $lr, 1 + renamable $r0 = t2ADDri renamable $lr, 2, 14, $noreg, $noreg $lr = tMOVr $r4, 14, $noreg t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr tB %bb.3, 14, $noreg bb.3.while.end: - $r0 = tMOVr killed $r4, 14, $noreg - tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 + liveins: $r0 + + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 bb.4: - renamable $r4, dead $cpsr = tMOVi8 0, 14, $noreg - $r0 = tMOVr killed $r4, 14, $noreg - tPOP_RET 14, $noreg, def $r4, def $r5, def $r7, def $pc, implicit killed $r0 + renamable $r0, dead $cpsr = tMOVi8 0, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 ... - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-loop.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-loop.mir index bcd80c70bb4..da171f5387a 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-loop.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-non-loop.mir @@ -14,6 +14,9 @@ # CHECK: bb.4.while.end: --- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + define void @non_loop(i16* nocapture %a, i16* nocapture readonly %b, i32 %N) { entry: %cmp = icmp ugt i32 %N, 2 @@ -23,19 +26,19 @@ %test = call i1 @llvm.test.set.loop.iterations.i32(i32 %N) br i1 %test, label %while.body.preheader, label %while.end - while.body.preheader: ; preds = %entry, %not.preheader + while.body.preheader: ; preds = %not.preheader, %entry %scevgep = getelementptr i16, i16* %a, i32 -1 %scevgep3 = getelementptr i16, i16* %b, i32 -1 br label %while.body - while.body: ; preds = %while.body.preheader, %while.body + while.body: ; preds = %while.body, %while.body.preheader %lsr.iv4 = phi i16* [ %scevgep3, %while.body.preheader ], [ %scevgep5, %while.body ] %lsr.iv = phi i16* [ %scevgep, %while.body.preheader ], [ %scevgep1, %while.body ] %count = phi i32 [ %count.next, %while.body ], [ %N, %while.body.preheader ] - %scevgep2 = getelementptr i16, i16* %lsr.iv, i32 1 - %scevgep6 = getelementptr i16, i16* %lsr.iv4, i32 1 - %load = load i16, i16* %scevgep6, align 2 - store i16 %load, i16* %scevgep2, align 2 + %scevgep7 = getelementptr i16, i16* %lsr.iv, i32 1 + %scevgep4 = getelementptr i16, i16* %lsr.iv4, i32 1 + %load = load i16, i16* %scevgep4, align 2 + store i16 %load, i16* %scevgep7, align 2 %count.next = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %count, i32 1) %cmp1 = icmp ne i32 %count.next, 0 %scevgep1 = getelementptr i16, i16* %lsr.iv, i32 1 @@ -46,13 +49,8 @@ ret void } - ; Function Attrs: noduplicate nounwind declare i1 @llvm.test.set.loop.iterations.i32(i32) #0 - - ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #0 - - ; Function Attrs: nounwind declare void @llvm.stackprotector(i8*, i8**) #1 attributes #0 = { noduplicate nounwind } @@ -67,7 +65,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -107,6 +105,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.1(0x40000000), %bb.2(0x40000000) + liveins: $r0, $r1, $r2, $r7, $lr frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 8 @@ -118,21 +117,24 @@ body: | bb.1.not.preheader: successors: %bb.2(0x40000000), %bb.4(0x40000000) + liveins: $lr, $r0, $r1 t2WhileLoopStart renamable $lr, %bb.4, implicit-def dead $cpsr tB %bb.2, 14, $noreg bb.2.while.body.preheader: successors: %bb.3(0x80000000) + liveins: $lr, $r0, $r1 renamable $r1, dead $cpsr = tSUBi8 killed renamable $r1, 2, 14, $noreg renamable $r0, dead $cpsr = tSUBi8 killed renamable $r0, 2, 14, $noreg bb.3.while.body: successors: %bb.3(0x7c000000), %bb.4(0x04000000) + liveins: $lr, $r0, $r1 - renamable $r2, renamable $r1 = t2LDRH_PRE killed renamable $r1, 2, 14, $noreg :: (load 2 from %ir.scevgep6) - early-clobber renamable $r0 = t2STRH_PRE killed renamable $r2, killed renamable $r0, 2, 14, $noreg :: (store 2 into %ir.scevgep2) + renamable $r2, renamable $r1 = t2LDRH_PRE killed renamable $r1, 2, 14, $noreg :: (load 2 from %ir.scevgep4) + early-clobber renamable $r0 = t2STRH_PRE killed renamable $r2, killed renamable $r0, 2, 14, $noreg :: (store 2 into %ir.scevgep7) renamable $lr = t2LoopDec killed renamable $lr, 1 t2LoopEnd renamable $lr, %bb.3, implicit-def dead $cpsr tB %bb.4, 14, $noreg diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir index 754d35ea89b..9e0944afbc0 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/revert-while.mir @@ -13,6 +13,9 @@ # CHECK-NEXT: tB %bb.3, 14 --- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + define void @ne_trip_count(i1 zeroext %t1, i32* nocapture %a, i32* nocapture readonly %b, i32 %N) #0 { entry: %0 = call i1 @llvm.test.set.loop.iterations.i32(i32 %N) @@ -23,15 +26,15 @@ %scevgep5 = getelementptr i32, i32* %b, i32 -1 br label %do.body - do.body: ; preds = %do.body.preheader, %do.body + do.body: ; preds = %do.body, %do.body.preheader %lsr.iv6 = phi i32* [ %scevgep5, %do.body.preheader ], [ %scevgep7, %do.body ] %lsr.iv = phi i32* [ %scevgep2, %do.body.preheader ], [ %scevgep3, %do.body ] %1 = phi i32 [ %2, %do.body ], [ %N, %do.body.preheader ] - %scevgep8 = getelementptr i32, i32* %lsr.iv6, i32 1 - %scevgep4 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep = getelementptr i32, i32* %lsr.iv6, i32 1 + %scevgep1 = getelementptr i32, i32* %lsr.iv, i32 1 %size = call i32 @llvm.arm.space(i32 4096, i32 undef) - %tmp = load i32, i32* %scevgep8, align 4 - store i32 %tmp, i32* %scevgep4, align 4 + %tmp = load i32, i32* %scevgep, align 4 + store i32 %tmp, i32* %scevgep1, align 4 %2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %1, i32 1) %3 = icmp ne i32 %2, 0 %scevgep3 = getelementptr i32, i32* %lsr.iv, i32 1 @@ -51,9 +54,6 @@ ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #2 - ; Function Attrs: nounwind - declare void @llvm.stackprotector(i8*, i8**) #1 - attributes #0 = { "target-features"="+lob" } attributes #1 = { nounwind } attributes #2 = { noduplicate nounwind } @@ -67,7 +67,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -107,6 +107,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.1(0x40000000), %bb.3(0x40000000) + liveins: $r1, $r2, $r3, $r7, $lr frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 8 @@ -117,6 +118,7 @@ body: | bb.1.do.body.preheader: successors: %bb.2(0x80000000) + liveins: $r1, $r2, $r3 renamable $r0, dead $cpsr = tSUBi3 killed renamable $r2, 4, 14, $noreg renamable $r1, dead $cpsr = tSUBi8 killed renamable $r1, 4, 14, $noreg @@ -124,10 +126,11 @@ body: | bb.2.do.body: successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r0, $r1 dead renamable $r2 = SPACE 4096, undef renamable $r0 - renamable $r2, renamable $r0 = t2LDR_PRE killed renamable $r0, 4, 14, $noreg :: (load 4 from %ir.scevgep8) - early-clobber renamable $r1 = t2STR_PRE killed renamable $r2, killed renamable $r1, 4, 14, $noreg :: (store 4 into %ir.scevgep4) + renamable $r2, renamable $r0 = t2LDR_PRE killed renamable $r0, 4, 14, $noreg :: (load 4 from %ir.scevgep) + early-clobber renamable $r1 = t2STR_PRE killed renamable $r2, killed renamable $r1, 4, 14, $noreg :: (store 4 into %ir.scevgep1) renamable $lr = t2LoopDec killed renamable $lr, 1 t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr tB %bb.3, 14, $noreg @@ -136,4 +139,3 @@ body: | tPOP_RET 14, $noreg, def $r7, def $pc ... - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/safe-def-no-mov.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/safe-def-no-mov.mir new file mode 100644 index 00000000000..efbee0e609c --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/safe-def-no-mov.mir @@ -0,0 +1,124 @@ +# RUN: llc -mtriple=thumbv8.1m.main -run-pass=arm-low-overhead-loops %s -verify-machineinstrs -o - | FileCheck %s +# CHECK: $lr = t2DLS $r0 +# CHECK: $lr = tMOVr $r0, 14 +# CHECK: $lr = t2LEUpdate renamable $lr, %bb.2 + +# TODO: Explore the preheader to remove the redundant tMOVr + +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + + define i32 @do_copy(i32 %n, i32* nocapture %p, i32* nocapture readonly %q) { + entry: + %scevgep = getelementptr i32, i32* %q, i32 -1 + %scevgep3 = getelementptr i32, i32* %p, i32 -1 + call void @llvm.set.loop.iterations.i32(i32 %n) + br label %preheader + + preheader: + br label %while.body + + while.body: ; preds = %while.body, %entry + %lsr.iv4 = phi i32* [ %scevgep5, %while.body ], [ %scevgep3, %preheader ] + %lsr.iv = phi i32* [ %scevgep1, %while.body ], [ %scevgep, %preheader ] + %0 = phi i32 [ %n, %preheader ], [ %2, %while.body ] + %scevgep6 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep2 = getelementptr i32, i32* %lsr.iv4, i32 1 + %1 = load i32, i32* %scevgep6, align 4 + store i32 %1, i32* %scevgep2, align 4 + %scevgep1 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep5 = getelementptr i32, i32* %lsr.iv4, i32 1 + %2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) + %3 = icmp ne i32 %2, 0 + br i1 %3, label %while.body, label %while.end + + while.end: ; preds = %while.body + ret i32 0 + } + + declare void @llvm.set.loop.iterations.i32(i32) #0 + declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #0 + + attributes #0 = { noduplicate nounwind } + attributes #1 = { nounwind } + +... +--- +name: do_copy +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$r0', virtual-reg: '' } + - { reg: '$r1', virtual-reg: '' } + - { reg: '$r2', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 8 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0.entry: + successors: %bb.1(0x80000000) + liveins: $r0, $r1, $r2, $r7, $lr + + frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 + frame-setup CFI_INSTRUCTION offset $lr, -4 + frame-setup CFI_INSTRUCTION offset $r7, -8 + t2DoLoopStart $r0 + renamable $r0, dead $cpsr = tSUBi3 killed renamable $r1, 4, 14, $noreg + renamable $r1, dead $cpsr = tSUBi3 killed renamable $r2, 4, 14, $noreg + + bb.1.preheader: + successors: %bb.2(0x80000000) + liveins: $r0 + $lr = tMOVr $r0, 14, $noreg + + bb.2.while.body: + successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r0, $r1 + + renamable $r2, renamable $r1 = t2LDR_PRE killed renamable $r1, 4, 14, $noreg :: (load 4 from %ir.scevgep6) + early-clobber renamable $r0 = t2STR_PRE killed renamable $r2, killed renamable $r0, 4, 14, $noreg :: (store 4 into %ir.scevgep2) + renamable $lr = t2LoopDec killed renamable $lr, 1 + t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr + tB %bb.3, 14, $noreg + + bb.3.while.end: + $r0, dead $cpsr = tMOVi8 0, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 + +... diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/unsafe-liveout.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/unsafe-liveout.mir new file mode 100644 index 00000000000..2c96665e638 --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/unsafe-liveout.mir @@ -0,0 +1,122 @@ +# RUN: llc -mtriple=thumbv8.1m.main -run-pass=arm-low-overhead-loops %s -verify-machineinstrs -o - | FileCheck %s +# CHECK-NOT: $lr = t2DLS +# CHECK: $lr = tMOVr $r0, 14 +# CHECK-NOT: $lr = t2LEUpdate + +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + + define i32 @do_copy(i32 %n, i32* nocapture %p, i32* nocapture readonly %q) { + entry: + %scevgep = getelementptr i32, i32* %q, i32 -1 + %scevgep3 = getelementptr i32, i32* %p, i32 -1 + call void @llvm.set.loop.iterations.i32(i32 %n) + br label %preheader + + preheader: + br label %while.body + + while.body: ; preds = %while.body, %entry + %lsr.iv4 = phi i32* [ %scevgep5, %while.body ], [ %scevgep3, %preheader ] + %lsr.iv = phi i32* [ %scevgep1, %while.body ], [ %scevgep, %preheader ] + %0 = phi i32 [ %n, %preheader ], [ %2, %while.body ] + %scevgep6 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep2 = getelementptr i32, i32* %lsr.iv4, i32 1 + %1 = load i32, i32* %scevgep6, align 4 + store i32 %1, i32* %scevgep2, align 4 + %scevgep1 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep5 = getelementptr i32, i32* %lsr.iv4, i32 1 + %2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) + %3 = icmp ne i32 %2, 0 + br i1 %3, label %while.body, label %while.end + + while.end: ; preds = %while.body + ret i32 0 + } + + declare void @llvm.set.loop.iterations.i32(i32) #0 + declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #0 + + attributes #0 = { noduplicate nounwind } + attributes #1 = { nounwind } + +... +--- +name: do_copy +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$r0', virtual-reg: '' } + - { reg: '$r1', virtual-reg: '' } + - { reg: '$r2', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 8 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0.entry: + successors: %bb.1(0x80000000) + liveins: $r0, $r1, $r2, $r7, $lr + + frame-setup tPUSH 14, $noreg, killed $r7, implicit-def $sp, implicit $sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 + frame-setup CFI_INSTRUCTION offset $lr, -4 + frame-setup CFI_INSTRUCTION offset $r7, -8 + t2DoLoopStart $r0 + renamable $r0, dead $cpsr = tSUBi3 killed renamable $r1, 4, 14, $noreg + renamable $r1, dead $cpsr = tSUBi3 killed renamable $r2, 4, 14, $noreg + + bb.1.preheader: + successors: %bb.2(0x80000000) + liveins: $r0, $lr + $lr = tMOVr $r0, 14, $noreg + + bb.2.while.body: + successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r0, $r1 + + renamable $r2, renamable $r1 = t2LDR_PRE killed renamable $r1, 4, 14, $noreg :: (load 4 from %ir.scevgep6) + early-clobber renamable $r0 = t2STR_PRE killed renamable $r2, killed renamable $r0, 4, 14, $noreg :: (store 4 into %ir.scevgep2) + renamable $lr = t2LoopDec killed renamable $lr, 1 + t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr + tB %bb.3, 14, $noreg + + bb.3.while.end: + $r0, dead $cpsr = tMOVi8 0, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 + +... diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/unsafe-use-after.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/unsafe-use-after.mir new file mode 100644 index 00000000000..15a76e6270a --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/unsafe-use-after.mir @@ -0,0 +1,122 @@ +# RUN: llc -mtriple=thumbv8.1m.main -run-pass=arm-low-overhead-loops %s -verify-machineinstrs -o - | FileCheck %s +# CHECK-NOT: $lr = t2DLS +# CHECK: $lr = tMOVr $r0, 14 +# CHECK-NOT: $lr = t2LEUpdate + +--- | + target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv8.1m.main" + + define i32 @do_copy(i32 %n, i32* nocapture %p, i32* nocapture readonly %q) { + entry: + %scevgep = getelementptr i32, i32* %q, i32 -1 + %scevgep3 = getelementptr i32, i32* %p, i32 -1 + call void @llvm.set.loop.iterations.i32(i32 %n) + br label %preheader + + preheader: + br label %while.body + + while.body: ; preds = %while.body, %entry + %lsr.iv4 = phi i32* [ %scevgep5, %while.body ], [ %scevgep3, %preheader ] + %lsr.iv = phi i32* [ %scevgep1, %while.body ], [ %scevgep, %preheader ] + %0 = phi i32 [ %n, %preheader ], [ %2, %while.body ] + %scevgep6 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep2 = getelementptr i32, i32* %lsr.iv4, i32 1 + %1 = load i32, i32* %scevgep6, align 4 + store i32 %1, i32* %scevgep2, align 4 + %scevgep1 = getelementptr i32, i32* %lsr.iv, i32 1 + %scevgep5 = getelementptr i32, i32* %lsr.iv4, i32 1 + %2 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %0, i32 1) + %3 = icmp ne i32 %2, 0 + br i1 %3, label %while.body, label %while.end + + while.end: ; preds = %while.body + ret i32 0 + } + + declare void @llvm.set.loop.iterations.i32(i32) #0 + declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #0 + + attributes #0 = { noduplicate nounwind } + attributes #1 = { nounwind } + +... +--- +name: do_copy +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$r0', virtual-reg: '' } + - { reg: '$r1', virtual-reg: '' } + - { reg: '$r2', virtual-reg: '' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 8 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: + - { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '$r7', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0.entry: + successors: %bb.1(0x80000000) + liveins: $r0, $r1, $r2, $r7, $lr + + frame-setup tPUSH 14, $noreg, killed $r7, implicit-def $sp, implicit $sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 + frame-setup CFI_INSTRUCTION offset $lr, -4 + frame-setup CFI_INSTRUCTION offset $r7, -8 + t2DoLoopStart $r0 + renamable $r0 = t2SUBri killed renamable $lr, 4, 14, $noreg, def $cpsr + renamable $r1, dead $cpsr = tSUBi3 killed renamable $r2, 4, 14, $noreg + + bb.1.preheader: + successors: %bb.2(0x80000000) + liveins: $r0 + $lr = tMOVr $r0, 14, $noreg + + bb.2.while.body: + successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r0, $r1 + + renamable $r2, renamable $r1 = t2LDR_PRE killed renamable $r1, 4, 14, $noreg :: (load 4 from %ir.scevgep6) + early-clobber renamable $r0 = t2STR_PRE killed renamable $r2, killed renamable $r0, 4, 14, $noreg :: (store 4 into %ir.scevgep2) + renamable $lr = t2LoopDec killed renamable $lr, 1 + t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr + tB %bb.3, 14, $noreg + + bb.3.while.end: + $r0, dead $cpsr = tMOVi8 0, 14, $noreg + tPOP_RET 14, $noreg, def $r7, def $pc, implicit killed $r0 + +... diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-negative-offset.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-negative-offset.mir index 9195b977224..cfafa427731 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-negative-offset.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-negative-offset.mir @@ -3,8 +3,6 @@ # CHECK-NOT: WhileLoopStart --- | - ; ModuleID = '/home/sampar01/src/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while-negative-offset.ll' - source_filename = "while-size-limit.ll" target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv8.1m.main" @@ -47,8 +45,10 @@ ; Function Attrs: nounwind declare i32 @llvm.arm.space(i32 immarg, i32) #1 + ; Function Attrs: noduplicate nounwind declare i1 @llvm.test.set.loop.iterations.i32(i32) #2 + ; Function Attrs: noduplicate nounwind declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #2 @@ -65,7 +65,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -130,6 +130,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.4(0x80000000) + liveins: $r0, $r1, $r2, $r3, $r4, $lr frame-setup tPUSH 14, $noreg, killed $r4, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 8 @@ -192,5 +193,3 @@ body: | tB %bb.2, 14, $noreg ... - - diff --git a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while.mir b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while.mir index e05adc6b474..b1559bd752b 100644 --- a/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while.mir +++ b/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while.mir @@ -10,8 +10,6 @@ # CHECK: $lr = t2LEUpdate renamable $lr --- | - ; ModuleID = '/home/sampar01/src/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while.ll' - source_filename = "/home/sampar01/src/llvm/test/CodeGen/Thumb2/LowOverheadLoops/while.ll" target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "thumbv8.1m.main" @@ -25,14 +23,14 @@ %scevgep3 = getelementptr i16, i16* %b, i32 -1 br label %while.body - while.body: ; preds = %while.body.preheader, %while.body + while.body: ; preds = %while.body, %while.body.preheader %lsr.iv4 = phi i16* [ %scevgep3, %while.body.preheader ], [ %scevgep5, %while.body ] %lsr.iv = phi i16* [ %scevgep, %while.body.preheader ], [ %scevgep1, %while.body ] %1 = phi i32 [ %3, %while.body ], [ %N, %while.body.preheader ] - %scevgep2 = getelementptr i16, i16* %lsr.iv, i32 1 - %scevgep6 = getelementptr i16, i16* %lsr.iv4, i32 1 - %2 = load i16, i16* %scevgep6, align 2, !tbaa !2 - store i16 %2, i16* %scevgep2, align 2, !tbaa !2 + %scevgep7 = getelementptr i16, i16* %lsr.iv, i32 1 + %scevgep4 = getelementptr i16, i16* %lsr.iv4, i32 1 + %2 = load i16, i16* %scevgep4, align 2 + store i16 %2, i16* %scevgep7, align 2 %3 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %1, i32 1) %4 = icmp ne i32 %3, 0 %scevgep1 = getelementptr i16, i16* %lsr.iv, i32 1 @@ -48,15 +46,6 @@ attributes #0 = { noduplicate nounwind } attributes #1 = { nounwind } - - !llvm.module.flags = !{!0, !1} - - !0 = !{i32 1, !"wchar_size", i32 4} - !1 = !{i32 1, !"min_enum_size", i32 4} - !2 = !{!3, !3, i64 0} - !3 = !{!"short", !4, i64 0} - !4 = !{!"omnipotent char", !5, i64 0} - !5 = !{!"Simple C/C++ TBAA"} ... --- @@ -67,7 +56,7 @@ legalized: false regBankSelected: false selected: false failedISel: false -tracksRegLiveness: false +tracksRegLiveness: true hasWinCFI: false registers: [] liveins: @@ -107,6 +96,7 @@ machineFunctionInfo: {} body: | bb.0.entry: successors: %bb.1(0x40000000), %bb.3(0x40000000) + liveins: $r0, $r1, $r2, $r7, $lr frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp frame-setup CFI_INSTRUCTION def_cfa_offset 8 @@ -117,6 +107,7 @@ body: | bb.1.while.body.preheader: successors: %bb.2(0x80000000) + liveins: $r0, $r1, $r2 renamable $r1, dead $cpsr = tSUBi8 killed renamable $r1, 2, 14, $noreg renamable $r0, dead $cpsr = tSUBi8 killed renamable $r0, 2, 14, $noreg @@ -124,9 +115,10 @@ body: | bb.2.while.body: successors: %bb.2(0x7c000000), %bb.3(0x04000000) + liveins: $lr, $r0, $r1 - renamable $r2, renamable $r1 = t2LDRH_PRE killed renamable $r1, 2, 14, $noreg :: (load 2 from %ir.scevgep6, !tbaa !2) - early-clobber renamable $r0 = t2STRH_PRE killed renamable $r2, killed renamable $r0, 2, 14, $noreg :: (store 2 into %ir.scevgep2, !tbaa !2) + renamable $r2, renamable $r1 = t2LDRH_PRE killed renamable $r1, 2, 14, $noreg :: (load 2 from %ir.scevgep4) + early-clobber renamable $r0 = t2STRH_PRE killed renamable $r2, killed renamable $r0, 2, 14, $noreg :: (store 2 into %ir.scevgep7) renamable $lr = t2LoopDec killed renamable $lr, 1 t2LoopEnd renamable $lr, %bb.2, implicit-def dead $cpsr tB %bb.3, 14, $noreg @@ -135,4 +127,3 @@ body: | tPOP_RET 14, $noreg, def $r7, def $pc ... - |