[ARM] ScheduleDAGRRList::DelayForLiveRegsBottomUp must consider OptionalDefs
Summary: D30400 has enabled tADC and tSBC instructions to be unglued, thereby allowing CPSR to remain live between Thumb1 scheduling units. Most Thumb1 instructions have an OptionalDef for CPSR; but the scheduler ignored the OptionalDefs, and could unwittingly insert a flag-setting instruction in between an ADDS and the corresponding ADC. Reviewers: javed.absar, atrick, MatzeB, t.p.northover, jmolloy, rengolin Reviewed By: javed.absar Subscribers: rogfer01, efriedma, aemerson, rengolin, llvm-commits, MatzeB Differential Revision: https://reviews.llvm.org/D31081 llvm-svn: 301106
This commit is contained in:
parent
474e5de72d
commit
53cf1897cc
|
@ -1320,6 +1320,18 @@ DelayForLiveRegsBottomUp(SUnit *SU, SmallVectorImpl<unsigned> &LRegs) {
|
|||
RegAdded, LRegs);
|
||||
|
||||
const MCInstrDesc &MCID = TII->get(Node->getMachineOpcode());
|
||||
if (MCID.hasOptionalDef()) {
|
||||
// Most ARM instructions have an OptionalDef for CPSR, to model the S-bit.
|
||||
// This operand can be either a def of CPSR, if the S bit is set; or a use
|
||||
// of %noreg. When the OptionalDef is set to a valid register, we need to
|
||||
// handle it in the same way as an ImplicitDef.
|
||||
for (unsigned i = 0; i < MCID.getNumDefs(); ++i)
|
||||
if (MCID.OpInfo[i].isOptionalDef()) {
|
||||
const SDValue &OptionalDef = Node->getOperand(i - Node->getNumValues());
|
||||
unsigned Reg = cast<RegisterSDNode>(OptionalDef)->getReg();
|
||||
CheckForLiveRegDef(SU, Reg, LiveRegDefs.get(), RegAdded, LRegs, TRI);
|
||||
}
|
||||
}
|
||||
if (!MCID.ImplicitDefs)
|
||||
continue;
|
||||
for (const MCPhysReg *Reg = MCID.getImplicitDefs(); *Reg; ++Reg)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
; RUN: llc -mtriple=thumb-eabi %s -verify-machineinstrs -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=thumbv6-eabi %s -verify-machineinstrs -o - | FileCheck %s
|
||||
|
||||
define i1 @test(i64 %arg) {
|
||||
entry:
|
||||
%ispos = icmp sgt i64 %arg, -1
|
||||
%neg = sub i64 0, %arg
|
||||
%sel = select i1 %ispos, i64 %arg, i64 %neg
|
||||
%cmp2 = icmp eq i64 %sel, %arg
|
||||
ret i1 %cmp2
|
||||
}
|
||||
|
||||
; The scheduler used to ignore OptionalDefs, and could unwittingly insert
|
||||
; a flag-setting instruction in between an ADDS and the corresponding ADC.
|
||||
|
||||
; CHECK: adds
|
||||
; CHECK-NOT: eors
|
||||
; CHECK: adcs
|
Loading…
Reference in New Issue