1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
# RUN: llc -mtriple=thumbv8.1m.main -mattr=+lob %s -run-pass=arm-low-overhead-loops --verify-machineinstrs -o - | FileCheck %s
# TODO: Remove the lr = tMOVr
# CHECK: body:
# CHECK: $lr = t2WLS $r2, [[EXIT:%bb[.0-9]+]]
# CHECK: [[PREHEADER:bb[.0-9a-z]+]]:
# CHECK: $lr = tMOVr killed $r2
# CHECK: [[BODY:bb[.0-9a-z]+]]:
# CHECK: $lr = t2LEUpdate renamable $lr
--- |
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv8.1m.main-arm-unknown"
; Function Attrs: norecurse nounwind optsize
define dso_local arm_aapcscc void @copy(i16* nocapture %a, i16* nocapture readonly %b, i32 %N) {
entry:
%cmp4 = icmp eq i32 %N, 0
%0 = call i1 @llvm.test.set.loop.iterations.i32(i32 %N)
br i1 %0, label %while.body.preheader, label %while.end
while.body.preheader: ; preds = %entry
br label %while.body
while.body: ; preds = %while.body, %while.body.preheader
%a.addr.06 = phi i16* [ %incdec.ptr1, %while.body ], [ %a, %while.body.preheader ]
%b.addr.05 = phi i16* [ %incdec.ptr, %while.body ], [ %b, %while.body.preheader ]
%1 = phi i32 [ %N, %while.body.preheader ], [ %3, %while.body ]
%incdec.ptr = getelementptr inbounds i16, i16* %b.addr.05, i32 1
%2 = load i16, i16* %b.addr.05, align 2, !tbaa !3
%incdec.ptr1 = getelementptr inbounds i16, i16* %a.addr.06, i32 1
store i16 %2, i16* %a.addr.06, align 2, !tbaa !3
%3 = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 %1, i32 1)
%4 = icmp ne i32 %3, 0
br i1 %4, label %while.body, label %while.end
while.end: ; preds = %while.body, %entry
ret void
}
declare i1 @llvm.test.set.loop.iterations.i32(i32) #1
declare i32 @llvm.loop.decrement.reg.i32.i32.i32(i32, i32) #1
attributes #1 = { noduplicate nounwind }
attributes #2 = { nounwind }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"min_enum_size", i32 4}
!3 = !{!4, !4, i64 0}
!4 = !{!"short", !5, i64 0}
!5 = !{!"omnipotent char", !6, i64 0}
!6 = !{!"Simple C/C++ TBAA"}
...
---
name: copy
alignment: 1
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
failedISel: false
tracksRegLiveness: false
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: '' }
constants: []
machineFunctionInfo: {}
body: |
bb.0.entry:
successors: %bb.1(0x40000000), %bb.3(0x40000000)
frame-setup tPUSH 14, $noreg, $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
$r7 = frame-setup tMOVr $sp, 14, $noreg
frame-setup CFI_INSTRUCTION def_cfa_register $r7
t2WhileLoopStart $r2, %bb.3
tB %bb.1, 14, $noreg
bb.1.while.body.preheader:
successors: %bb.2(0x80000000)
$lr = tMOVr killed $r2, 14, $noreg
bb.2.while.body:
successors: %bb.2(0x7c000000), %bb.3(0x04000000)
renamable $r2, renamable $r1 = t2LDRH_POST killed renamable $r1, 2, 14, $noreg :: (load 2 from %ir.b.addr.05, !tbaa !3)
early-clobber renamable $r0 = t2STRH_POST killed renamable $r2, killed renamable $r0, 2, 14, $noreg :: (store 2 into %ir.a.addr.06, !tbaa !3)
renamable $lr = t2LoopDec killed renamable $lr, 1
t2LoopEnd renamable $lr, %bb.2
tB %bb.3, 14, $noreg
bb.3.while.end:
tPOP_RET 14, $noreg, def $r7, def $pc
...
|