Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add t2TEQrr to the map of instructions with can be reduced down into a T1 instruction. This is a special case because TEQ just sets the CPSR and doesn't write to a GPR, which is not the case for EOR. So, we need to ensure that the EOR can write to the first operand. Differential Revision: https://reviews.llvm.org/D56255 llvm-svn: 350801
- Loading branch information
1 parent
5d20eb2
commit 7208221
Showing
3 changed files
with
298 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,267 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py | ||
# RUN: llc -run-pass=t2-reduce-size %s -o - | FileCheck %s | ||
|
||
--- | | ||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" | ||
target triple = "thumbv8m.main" | ||
|
||
%list_head = type { %list_head*, %list_data* } | ||
%list_data = type { i16, i16 } | ||
|
||
define %list_head* @reg_reg_it_block(%list_head* %a, i16 zeroext %b) { | ||
entry: | ||
br label %while.begin | ||
|
||
while.begin: ; preds = %while.body.end, %entry | ||
%list.addr.i = phi %list_head* [ %ld.5, %while.body.end ], [ %a, %entry ] | ||
%info.i = getelementptr inbounds %list_head, %list_head* %list.addr.i, i32 0, i32 1 | ||
%ld.0 = load %list_data*, %list_data** %info.i, align 4 | ||
%data16.i1 = bitcast %list_data* %ld.0 to i16* | ||
%ld.1 = load i16, i16* %data16.i1, align 2 | ||
%xor.1 = xor i16 %ld.1, %b | ||
%cmp.i = icmp eq i16 %xor.1, 0 | ||
br i1 %cmp.i, label %exit, label %while.body.a | ||
|
||
while.body.a: ; preds = %while.begin | ||
%next.i2 = bitcast %list_head* %list.addr.i to %list_head** | ||
%ld.2 = load %list_head*, %list_head** %next.i2, align 4 | ||
%cmp.i.1 = icmp eq %list_head* %ld.2, null | ||
br i1 %cmp.i.1, label %exit, label %it.block | ||
|
||
it.block: ; preds = %while.body.a | ||
%info.i.1 = getelementptr inbounds %list_head, %list_head* %ld.2, i32 0, i32 1 | ||
%ld.3 = load %list_data*, %list_data** %info.i.1, align 4 | ||
%data16.i.13 = bitcast %list_data* %ld.3 to i16* | ||
%ld.4 = load i16, i16* %data16.i.13, align 2 | ||
%xor.2 = xor i16 %ld.4, %b | ||
%cmp.i.2 = icmp eq i16 %xor.2, 0 | ||
br i1 %cmp.i.2, label %exit, label %while.body.end | ||
|
||
while.body.end: ; preds = %it.block | ||
%next.i.14 = bitcast %list_head* %ld.2 to %list_head** | ||
%ld.5 = load %list_head*, %list_head** %next.i.14, align 4 | ||
%cmp.i.3 = icmp eq %list_head* %ld.5, null | ||
br i1 %cmp.i.3, label %exit, label %while.begin | ||
|
||
exit: ; preds = %while.body.end, %it.block, %while.body.a, %while.begin | ||
%res = phi %list_head* [ %list.addr.i, %while.begin ], [ %ld.2, %while.body.a ], [ %ld.2, %it.block ], [ %ld.5, %while.body.end ] | ||
ret %list_head* %res | ||
} | ||
|
||
define i16 @op_not_killed(%list_head* %a, i16 zeroext %b) { | ||
entry: | ||
br label %while.begin | ||
|
||
while.begin: ; preds = %while.body.end, %entry | ||
%list.addr.i = phi %list_head* [ %ld.5, %while.body.end ], [ %a, %entry ] | ||
%info.i = getelementptr inbounds %list_head, %list_head* %list.addr.i, i32 0, i32 1 | ||
%ld.0 = load %list_data*, %list_data** %info.i, align 4 | ||
%data16.i1 = bitcast %list_data* %ld.0 to i16* | ||
%ld.1 = load i16, i16* %data16.i1, align 2 | ||
%xor.1 = xor i16 %ld.1, %b | ||
%cmp.i = icmp eq i16 %xor.1, 0 | ||
br i1 %cmp.i, label %exit, label %while.body.a | ||
|
||
while.body.a: ; preds = %while.begin | ||
%next.i2 = bitcast %list_head* %list.addr.i to %list_head** | ||
%ld.2 = load %list_head*, %list_head** %next.i2, align 4 | ||
%cmp.i.1 = icmp eq %list_head* %ld.2, null | ||
br i1 %cmp.i.1, label %exit, label %it.block | ||
|
||
it.block: ; preds = %while.body.a | ||
%info.i.1 = getelementptr inbounds %list_head, %list_head* %ld.2, i32 0, i32 1 | ||
%ld.3 = load %list_data*, %list_data** %info.i.1, align 4 | ||
%data16.i.13 = bitcast %list_data* %ld.3 to i16* | ||
%ld.4 = load i16, i16* %data16.i.13, align 2 | ||
%xor.2 = xor i16 %ld.4, %b | ||
%cmp.i.2 = icmp eq i16 %xor.2, 0 | ||
br i1 %cmp.i.2, label %exit, label %while.body.end | ||
|
||
while.body.end: ; preds = %it.block | ||
%next.i.14 = bitcast %list_head* %ld.2 to %list_head** | ||
%ld.5 = load %list_head*, %list_head** %next.i.14, align 4 | ||
%cmp.i.3 = icmp eq %list_head* %ld.5, null | ||
br i1 %cmp.i.3, label %exit, label %while.begin | ||
|
||
exit: ; preds = %while.body.end, %it.block, %while.body.a, %while.begin | ||
%res = phi i16 [ %ld.1, %while.begin ], [ %ld.1, %while.body.a ], [ %ld.4, %it.block ], [ %ld.4, %while.body.end ] | ||
ret i16 %res | ||
} | ||
|
||
... | ||
--- | ||
name: reg_reg_it_block | ||
tracksRegLiveness: true | ||
liveins: | ||
- { reg: '$r0', virtual-reg: '' } | ||
- { reg: '$r1', virtual-reg: '' } | ||
body: | | ||
; CHECK-LABEL: name: reg_reg_it_block | ||
; CHECK: bb.0.entry: | ||
; CHECK: successors: %bb.2(0x80000000) | ||
; CHECK: liveins: $r0, $r1 | ||
; CHECK: t2B %bb.2, 14, $noreg | ||
; CHECK: bb.1.while.body.end: | ||
; CHECK: successors: %bb.2(0x80000000) | ||
; CHECK: liveins: $r0, $r1 | ||
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i.14) | ||
; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr | ||
; CHECK: BUNDLE implicit-def dead $itstate, implicit killed $cpsr, implicit $r0 { | ||
; CHECK: t2IT 0, 8, implicit-def $itstate | ||
; CHECK: tBX_RET 0, killed $cpsr, implicit $r0, implicit internal killed $itstate | ||
; CHECK: } | ||
; CHECK: bb.2.while.begin: | ||
; CHECK: successors: %bb.4(0x04000000), %bb.3(0x7c000000) | ||
; CHECK: liveins: $r0, $r1 | ||
; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 14, $noreg :: (load 4 from %ir.info.i) | ||
; CHECK: renamable $r2 = tLDRHi killed renamable $r2, 0, 14, $noreg :: (load 2 from %ir.data16.i1) | ||
; CHECK: dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14, $noreg | ||
; CHECK: t2Bcc %bb.4, 0, killed $cpsr | ||
; CHECK: bb.3.while.body.a: | ||
; CHECK: successors: %bb.4(0x4207fef8), %bb.1(0x3df80108) | ||
; CHECK: liveins: $r0, $r1 | ||
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i2) | ||
; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr | ||
; CHECK: BUNDLE implicit-def dead $itstate, implicit-def dead $r2, implicit-def $cpsr, implicit $r0, implicit killed $cpsr, implicit $r1 { | ||
; CHECK: t2IT 1, 30, implicit-def $itstate | ||
; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 1, $cpsr, implicit internal $itstate :: (load 4 from %ir.info.i.1) | ||
; CHECK: renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load 2 from %ir.data16.i.13) | ||
; CHECK: t2TEQrr internal killed renamable $r2, renamable $r1, 1, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate | ||
; CHECK: } | ||
; CHECK: t2Bcc %bb.1, 1, killed $cpsr | ||
; CHECK: bb.4.exit: | ||
; CHECK: liveins: $r0 | ||
; CHECK: tBX_RET 14, $noreg, implicit killed $r0 | ||
bb.0.entry: | ||
successors: %bb.1(0x80000000) | ||
liveins: $r0, $r1 | ||
t2B %bb.1, 14, $noreg | ||
bb.3.while.body.end: | ||
successors: %bb.1(0x80000000) | ||
liveins: $r0, $r1 | ||
renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i.14) | ||
tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr | ||
BUNDLE implicit-def dead $itstate, implicit killed $cpsr, implicit $r0 { | ||
t2IT 0, 8, implicit-def $itstate | ||
tBX_RET 0, killed $cpsr, implicit $r0, implicit internal killed $itstate | ||
} | ||
bb.1.while.begin: | ||
successors: %bb.4(0x04000000), %bb.2(0x7c000000) | ||
liveins: $r0, $r1 | ||
renamable $r2 = tLDRi renamable $r0, 1, 14, $noreg :: (load 4 from %ir.info.i) | ||
renamable $r2 = tLDRHi killed renamable $r2, 0, 14, $noreg :: (load 2 from %ir.data16.i1) | ||
dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14, $noreg | ||
t2Bcc %bb.4, 0, killed $cpsr | ||
bb.2.while.body.a: | ||
successors: %bb.4(0x80000000), %bb.3(0x78200000) | ||
liveins: $r0, $r1 | ||
renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i2) | ||
tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr | ||
BUNDLE implicit-def dead $itstate, implicit-def dead $r2, implicit-def $cpsr, implicit $r0, implicit killed $cpsr, implicit $r1 { | ||
t2IT 1, 30, implicit-def $itstate | ||
renamable $r2 = tLDRi renamable $r0, 1, 1, $cpsr, implicit internal $itstate :: (load 4 from %ir.info.i.1) | ||
renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load 2 from %ir.data16.i.13) | ||
t2TEQrr internal killed renamable $r2, renamable $r1, 1, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate | ||
} | ||
t2Bcc %bb.3, 1, killed $cpsr | ||
bb.4.exit: | ||
liveins: $r0 | ||
tBX_RET 14, $noreg, implicit killed $r0 | ||
... | ||
--- | ||
name: op_not_killed | ||
tracksRegLiveness: true | ||
liveins: | ||
- { reg: '$r0', virtual-reg: '' } | ||
- { reg: '$r1', virtual-reg: '' } | ||
body: | | ||
; CHECK-LABEL: name: op_not_killed | ||
; CHECK: bb.0.entry: | ||
; CHECK: successors: %bb.1(0x80000000) | ||
; CHECK: liveins: $r0, $r1 | ||
; CHECK: $r2 = tMOVr $r0, 14, $noreg | ||
; CHECK: bb.1.while.begin: | ||
; CHECK: successors: %bb.5(0x04000000), %bb.2(0x7c000000) | ||
; CHECK: liveins: $r1, $r2 | ||
; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14, $noreg :: (load 4 from %ir.info.i) | ||
; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i1) | ||
; CHECK: t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr | ||
; CHECK: t2Bcc %bb.5, 0, killed $cpsr | ||
; CHECK: bb.2.while.body.a: | ||
; CHECK: successors: %bb.5(0x04000000), %bb.3(0x7c000000) | ||
; CHECK: liveins: $r0, $r1, $r2 | ||
; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i2) | ||
; CHECK: tCMPi8 renamable $r2, 0, 14, $noreg, implicit-def $cpsr | ||
; CHECK: t2Bcc %bb.5, 0, killed $cpsr | ||
; CHECK: bb.3.it.block: | ||
; CHECK: successors: %bb.5(0x04000000), %bb.4(0x7c000000) | ||
; CHECK: liveins: $r1, $r2 | ||
; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14, $noreg :: (load 4 from %ir.info.i.1) | ||
; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i.13) | ||
; CHECK: t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr | ||
; CHECK: t2Bcc %bb.5, 0, killed $cpsr | ||
; CHECK: bb.4.while.body.end: | ||
; CHECK: successors: %bb.5(0x04000000), %bb.1(0x7c000000) | ||
; CHECK: liveins: $r0, $r1, $r2 | ||
; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i.14) | ||
; CHECK: tCMPi8 renamable $r2, 0, 14, $noreg, implicit-def $cpsr | ||
; CHECK: t2Bcc %bb.1, 1, killed $cpsr | ||
; CHECK: bb.5.exit: | ||
; CHECK: liveins: $r0 | ||
; CHECK: tBX_RET 14, $noreg, implicit $r0 | ||
bb.0.entry: | ||
successors: %bb.1(0x80000000) | ||
liveins: $r0, $r1 | ||
$r2 = tMOVr $r0, 14, $noreg | ||
bb.1.while.begin: | ||
successors: %bb.5(0x04000000), %bb.2(0x7c000000) | ||
liveins: $r1, $r2 | ||
renamable $r0 = t2LDRi12 renamable $r2, 4, 14, $noreg :: (load 4 from %ir.info.i) | ||
renamable $r0 = t2LDRHi12 killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i1) | ||
t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr | ||
t2Bcc %bb.5, 0, killed $cpsr | ||
bb.2.while.body.a: | ||
successors: %bb.5(0x04000000), %bb.3(0x7c000000) | ||
liveins: $r0, $r1, $r2 | ||
renamable $r2 = t2LDRi12 killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i2) | ||
t2CMPri renamable $r2, 0, 14, $noreg, implicit-def $cpsr | ||
t2Bcc %bb.5, 0, killed $cpsr | ||
bb.3.it.block: | ||
successors: %bb.5(0x04000000), %bb.4(0x7c000000) | ||
liveins: $r1, $r2 | ||
renamable $r0 = t2LDRi12 renamable $r2, 4, 14, $noreg :: (load 4 from %ir.info.i.1) | ||
renamable $r0 = t2LDRHi12 killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i.13) | ||
t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr | ||
t2Bcc %bb.5, 0, killed $cpsr | ||
bb.4.while.body.end: | ||
successors: %bb.5(0x04000000), %bb.1(0x7c000000) | ||
liveins: $r0, $r1, $r2 | ||
renamable $r2 = t2LDRi12 killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i.14) | ||
t2CMPri renamable $r2, 0, 14, $noreg, implicit-def $cpsr | ||
t2Bcc %bb.1, 1, killed $cpsr | ||
bb.5.exit: | ||
liveins: $r0 | ||
tBX_RET 14, $noreg, implicit $r0 | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters