[ARM] Ensure undef is propagated to CBZ/CBNZ flags

In some rare circumstances we can be using an undef register for a
compare. When folded into a CBZ/CBNZ the undef flags are lost, leading
to machine verifier problems. This propagates the existing flags to the
new instruction.
This commit is contained in:
David Green 2021-03-03 08:02:58 +00:00
parent 4307069df4
commit ab280cbaa3
6 changed files with 105 additions and 28 deletions

View File

@ -1986,7 +1986,8 @@ bool ARMConstantIslands::optimizeThumb2Branches() {
LLVM_DEBUG(dbgs() << "Fold: " << *Cmp.MI << " and: " << *Br.MI);
MachineInstr *NewBR =
BuildMI(*MBB, Br.MI, Br.MI->getDebugLoc(), TII->get(Cmp.NewOpc))
.addReg(Reg, getKillRegState(RegKilled))
.addReg(Reg, getKillRegState(RegKilled) |
getRegState(Cmp.MI->getOperand(0)))
.addMBB(DestBB, Br.MI->getOperand(0).getTargetFlags());
Cmp.MI->eraseFromParent();

View File

@ -117,7 +117,7 @@ body: |
; CHECK-LOB: bb.1.while.cond.preheader:
; CHECK-LOB: successors: %bb.9(0x30000000), %bb.2(0x50000000)
; CHECK-LOB: liveins: $r0, $r2
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: bb.2.land.rhs.preheader:
; CHECK-LOB: successors: %bb.3(0x80000000)
; CHECK-LOB: liveins: $r0, $r2
@ -134,12 +134,12 @@ body: |
; CHECK-LOB: successors: %bb.9(0x04000000), %bb.3(0x7c000000)
; CHECK-LOB: liveins: $r0, $r1
; CHECK-LOB: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next4)
; CHECK-LOB: tCBNZ $r0, %bb.9
; CHECK-LOB: tCBNZ renamable $r0, %bb.9
; CHECK-LOB: t2LE %bb.3
; CHECK-LOB: bb.5.while.cond9.preheader:
; CHECK-LOB: successors: %bb.9(0x30000000), %bb.6(0x50000000)
; CHECK-LOB: liveins: $r0, $r1
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: bb.6.land.rhs11.lr.ph:
; CHECK-LOB: successors: %bb.7(0x80000000)
; CHECK-LOB: liveins: $r0, $r1
@ -155,7 +155,7 @@ body: |
; CHECK-LOB: successors: %bb.9(0x04000000), %bb.7(0x7c000000)
; CHECK-LOB: liveins: $r0, $r1
; CHECK-LOB: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next206)
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: t2LE %bb.7
; CHECK-LOB: bb.9:
; CHECK-LOB: successors: %bb.10(0x80000000)
@ -173,7 +173,7 @@ body: |
; CHECK-NOLOB: bb.1.while.cond.preheader:
; CHECK-NOLOB: successors: %bb.9(0x30000000), %bb.2(0x50000000)
; CHECK-NOLOB: liveins: $r0, $r2
; CHECK-NOLOB: tCBZ $r0, %bb.9
; CHECK-NOLOB: tCBZ renamable $r0, %bb.9
; CHECK-NOLOB: bb.2.land.rhs.preheader:
; CHECK-NOLOB: successors: %bb.3(0x80000000)
; CHECK-NOLOB: liveins: $r0, $r2
@ -196,7 +196,7 @@ body: |
; CHECK-NOLOB: bb.5.while.cond9.preheader:
; CHECK-NOLOB: successors: %bb.9(0x30000000), %bb.6(0x50000000)
; CHECK-NOLOB: liveins: $r0, $r1
; CHECK-NOLOB: tCBZ $r0, %bb.9
; CHECK-NOLOB: tCBZ renamable $r0, %bb.9
; CHECK-NOLOB: bb.6.land.rhs11.lr.ph:
; CHECK-NOLOB: successors: %bb.7(0x80000000)
; CHECK-NOLOB: liveins: $r0, $r1

View File

@ -121,7 +121,7 @@ body: |
; CHECK-LOB: bb.1.while.cond.preheader:
; CHECK-LOB: successors: %bb.9(0x30000000), %bb.2(0x50000000)
; CHECK-LOB: liveins: $r0, $r2
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: bb.2.land.rhs.preheader:
; CHECK-LOB: successors: %bb.3(0x80000000)
; CHECK-LOB: liveins: $r0, $r2
@ -138,12 +138,12 @@ body: |
; CHECK-LOB: successors: %bb.9(0x04000000), %bb.3(0x7c000000)
; CHECK-LOB: liveins: $r0, $r1
; CHECK-LOB: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next4)
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: t2LE %bb.3
; CHECK-LOB: bb.5.while.cond9.preheader:
; CHECK-LOB: successors: %bb.9(0x30000000), %bb.6(0x50000000)
; CHECK-LOB: liveins: $r0, $r1
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: bb.6.land.rhs11.lr.ph:
; CHECK-LOB: successors: %bb.7(0x80000000)
; CHECK-LOB: liveins: $r0, $r1
@ -159,7 +159,7 @@ body: |
; CHECK-LOB: successors: %bb.9(0x04000000), %bb.7(0x7c000000)
; CHECK-LOB: liveins: $r0, $r1
; CHECK-LOB: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.next206)
; CHECK-LOB: tCBZ $r0, %bb.9
; CHECK-LOB: tCBZ renamable $r0, %bb.9
; CHECK-LOB: t2LE %bb.7
; CHECK-LOB: bb.9:
; CHECK-LOB: successors: %bb.10(0x80000000)
@ -177,7 +177,7 @@ body: |
; CHECK-NOLOB: bb.1.while.cond.preheader:
; CHECK-NOLOB: successors: %bb.9(0x30000000), %bb.2(0x50000000)
; CHECK-NOLOB: liveins: $r0, $r2
; CHECK-NOLOB: tCBZ $r0, %bb.9
; CHECK-NOLOB: tCBZ renamable $r0, %bb.9
; CHECK-NOLOB: bb.2.land.rhs.preheader:
; CHECK-NOLOB: successors: %bb.3(0x80000000)
; CHECK-NOLOB: liveins: $r0, $r2
@ -200,7 +200,7 @@ body: |
; CHECK-NOLOB: bb.5.while.cond9.preheader:
; CHECK-NOLOB: successors: %bb.9(0x30000000), %bb.6(0x50000000)
; CHECK-NOLOB: liveins: $r0, $r1
; CHECK-NOLOB: tCBZ $r0, %bb.9
; CHECK-NOLOB: tCBZ renamable $r0, %bb.9
; CHECK-NOLOB: bb.6.land.rhs11.lr.ph:
; CHECK-NOLOB: successors: %bb.7(0x80000000)
; CHECK-NOLOB: liveins: $r0, $r1

View File

@ -190,7 +190,7 @@ body: |
; CHECK: successors: %bb.4(0x04000000), %bb.3(0x7c000000)
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: renamable $r3, dead $cpsr = tAND killed renamable $r3, renamable $r0, 14 /* CC::al */, $noreg
; CHECK: tCBZ $r2, %bb.4
; CHECK: tCBZ renamable $r2, %bb.4
; CHECK: t2LE %bb.3
; CHECK: bb.4.if.end:
; CHECK: liveins: $r1, $r3
@ -214,56 +214,56 @@ body: |
; CHECK: renamable $r0 = t2CSINC $zr, $zr, 10, implicit killed $cpsr
; CHECK: renamable $r0 = t2ANDrr killed renamable $r0, killed renamable $r1, 14 /* CC::al */, $noreg, $noreg
; CHECK: tSTRi killed renamable $r0, renamable $r2, 0, 14 /* CC::al */, $noreg :: (store 4 into @e)
; CHECK: tCBZ $r3, %bb.7
; CHECK: tCBZ renamable $r3, %bb.7
; CHECK: t2LE %bb.6
; CHECK: bb.7.if.end.us.us.us:
; CHECK: successors: %bb.8(0x40000000), %bb.6(0x40000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.8
; CHECK: tCBZ renamable $r3, %bb.8
; CHECK: t2LE %bb.6
; CHECK: bb.8.if.end.us.us.us.1:
; CHECK: successors: %bb.9(0x40000000), %bb.6(0x40000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.9
; CHECK: tCBZ renamable $r3, %bb.9
; CHECK: t2LE %bb.6
; CHECK: bb.9.if.end.us.us.us.2:
; CHECK: successors: %bb.10(0x40000000), %bb.6(0x40000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.10
; CHECK: tCBZ renamable $r3, %bb.10
; CHECK: t2LE %bb.6
; CHECK: bb.10.if.end.us.us.us.3:
; CHECK: successors: %bb.11(0x40000000), %bb.6(0x40000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.11
; CHECK: tCBZ renamable $r3, %bb.11
; CHECK: t2LE %bb.6
; CHECK: bb.11.if.end.us.us.us.4:
; CHECK: successors: %bb.12(0x40000000), %bb.6(0x40000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.12
; CHECK: tCBZ renamable $r3, %bb.12
; CHECK: t2LE %bb.6
; CHECK: bb.12.if.end.us.us.us.5:
; CHECK: successors: %bb.13(0x40000000), %bb.6(0x40000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.13
; CHECK: tCBZ renamable $r3, %bb.13
; CHECK: t2LE %bb.6
; CHECK: bb.13.if.end.us.us.us.6:
; CHECK: successors: %bb.14(0x04000000), %bb.6(0x7c000000)
; CHECK: liveins: $lr, $r2, $r12
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
; CHECK: renamable $r3 = t2LDRi12 renamable $r12, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @d)
; CHECK: tCBZ $r3, %bb.14
; CHECK: tCBZ renamable $r3, %bb.14
; CHECK: t2LE %bb.6
; CHECK: bb.14.if.end.us.us.us.7:
; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */
@ -284,7 +284,7 @@ body: |
; CHECK: successors: %bb.17(0x04000000), %bb.16(0x7c000000)
; CHECK: liveins: $r0, $r1, $r2, $r3
; CHECK: renamable $r3, dead $cpsr = tAND killed renamable $r3, renamable $r2, 14 /* CC::al */, $noreg
; CHECK: tCBZ $r0, %bb.17
; CHECK: tCBZ renamable $r0, %bb.17
; CHECK: t2LE %bb.16
; CHECK: bb.17.if.end.us38:
; CHECK: liveins: $r1, $r3

View File

@ -24,7 +24,7 @@ body: |
; CHECK: bb.0:
; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000)
; CHECK: liveins: $r0, $r1
; CHECK: tCBZ $r0, %bb.2
; CHECK: tCBZ renamable $r0, %bb.2
; CHECK: bb.1:
; CHECK: liveins: $r0
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.x)
@ -63,7 +63,7 @@ body: |
; CHECK: liveins: $r0, $r1
; CHECK: renamable $r0, $cpsr = tADDrr killed renamable $r0, renamable $r1, 14 /* CC::al */, $noreg
; CHECK: renamable $r1 = t2ADDrs renamable $r0, killed renamable $r1, 18, 14 /* CC::al */, $noreg, $noreg
; CHECK: tCBZ $r0, %bb.2
; CHECK: tCBZ renamable $r0, %bb.2
; CHECK: bb.1:
; CHECK: liveins: $r0
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.x)
@ -143,7 +143,7 @@ body: |
; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000)
; CHECK: liveins: $r0, $r1
; CHECK: renamable $r1 = t2ADDrs renamable $r0, killed renamable $r1, 18, 14 /* CC::al */, $noreg, $noreg
; CHECK: tCBZ $r0, %bb.2
; CHECK: tCBZ renamable $r0, %bb.2
; CHECK: bb.1:
; CHECK: liveins: $r0
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.x)
@ -222,7 +222,7 @@ body: |
; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000)
; CHECK: liveins: $r0, $r1
; CHECK: renamable $r0 = t2ADDrs killed renamable $r0, killed renamable $r0, 18, 14 /* CC::al */, $noreg, $noreg
; CHECK: tCBZ killed $r1, %bb.2
; CHECK: tCBZ killed renamable $r1, %bb.2
; CHECK: bb.1:
; CHECK: liveins: $r0
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.x)
@ -261,7 +261,7 @@ body: |
; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000)
; CHECK: liveins: $r0, $r1
; CHECK: renamable $r0 = t2ADDrs renamable $r1, killed renamable $r0, 18, 14 /* CC::al */, $noreg, $noreg
; CHECK: tCBZ killed $r1, %bb.2
; CHECK: tCBZ killed renamable $r1, %bb.2
; CHECK: bb.1:
; CHECK: liveins: $r0
; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (load 4 from %ir.x)

View File

@ -0,0 +1,76 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=thumbv7m-none-eabi -run-pass=arm-cp-islands -verify-machineinstrs -o - %s | FileCheck %s
--- |
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-none-eabi"
@a = global i32 0, align 4
@b = local_unnamed_addr global i32 0, align 4
define i32 @c() {
entry:
br i1 icmp eq (i8 trunc (i32 sdiv (i32 zext (i8 trunc (i32 lshr (i32 zext (i8 ptrtoint (i32* @a to i8) to i32), i32 6) to i8) to i32), i32 7) to i8), i8 0), label %if.then, label %safe_mod_func_int32_t_s_s.exit
safe_mod_func_int32_t_s_s.exit: ; preds = %entry
br i1 icmp eq (i32 srem (i32 6, i32 zext (i8 trunc (i32 sdiv (i32 zext (i8 trunc (i32 lshr (i32 zext (i8 ptrtoint (i32* @a to i8) to i32), i32 6) to i8) to i32), i32 7) to i8) to i32)), i32 0), label %if.end, label %if.then
if.then: ; preds = %safe_mod_func_int32_t_s_s.exit, %entry
%0 = load i32, i32* @b, align 4
%inc = add nsw i32 %0, 1
store i32 %inc, i32* @b, align 4
br label %if.end
if.end: ; preds = %if.then, %safe_mod_func_int32_t_s_s.exit
ret i32 undef
}
...
---
name: c
alignment: 2
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: c
; CHECK: bb.0.entry:
; CHECK: successors: %bb.2(0x40000000), %bb.1(0x40000000)
; CHECK: renamable $r0, dead $cpsr = tMOVi8 1, 14 /* CC::al */, $noreg
; CHECK: tCBNZ killed renamable $r0, %bb.2
; CHECK: bb.1.safe_mod_func_int32_t_s_s.exit:
; CHECK: successors: %bb.3(0x40000000), %bb.2(0x40000000)
; CHECK: tCBZ undef renamable $r0, %bb.3
; CHECK: bb.2.if.then:
; CHECK: successors: %bb.3(0x80000000)
; CHECK: $r0 = t2MOVi16 target-flags(arm-lo16) @b, 14 /* CC::al */, $noreg
; CHECK: $r0 = t2MOVTi16 killed $r0, target-flags(arm-hi16) @b, 14 /* CC::al */, $noreg
; CHECK: renamable $r1 = tLDRi renamable $r0, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @b)
; CHECK: renamable $r1, dead $cpsr = nsw tADDi8 killed renamable $r1, 1, 14 /* CC::al */, $noreg
; CHECK: tSTRi killed renamable $r1, killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (store 4 into @b)
; CHECK: bb.3.if.end:
; CHECK: tBX_RET 14 /* CC::al */, $noreg, implicit undef $r0
bb.0.entry:
successors: %bb.2(0x40000000), %bb.1(0x40000000)
renamable $r0, dead $cpsr = tMOVi8 1, 14 /* CC::al */, $noreg
tCMPi8 killed renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
t2Bcc %bb.2, 1 /* CC::ne */, killed $cpsr
bb.1.safe_mod_func_int32_t_s_s.exit:
successors: %bb.3(0x40000000), %bb.2(0x40000000)
tCMPi8 undef renamable $r0, 0, 14 /* CC::al */, $noreg, implicit-def $cpsr
t2Bcc %bb.3, 0 /* CC::eq */, killed $cpsr
bb.2.if.then:
successors: %bb.3(0x80000000)
$r0 = t2MOVi16 target-flags(arm-lo16) @b, 14 /* CC::al */, $noreg
$r0 = t2MOVTi16 killed $r0, target-flags(arm-hi16) @b, 14 /* CC::al */, $noreg
renamable $r1 = tLDRi renamable $r0, 0, 14 /* CC::al */, $noreg :: (dereferenceable load 4 from @b)
renamable $r1, dead $cpsr = nsw tADDi8 killed renamable $r1, 1, 14 /* CC::al */, $noreg
tSTRi killed renamable $r1, killed renamable $r0, 0, 14 /* CC::al */, $noreg :: (store 4 into @b)
bb.3.if.end:
tBX_RET 14 /* CC::al */, $noreg, implicit undef $r0
...