forked from OSchip/llvm-project
ARM: optimizeSelect has to consider the previous register class
optimizeSelect folds (predicated) copy instructions, it must not ignore the original register class of the operand when replacing the register with the copies dest register. llvm-svn: 191963
This commit is contained in:
parent
c22630e164
commit
2f169f900b
|
@ -1706,7 +1706,7 @@ MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI,
|
||||||
bool PreferFalse) const {
|
bool PreferFalse) const {
|
||||||
assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
|
assert((MI->getOpcode() == ARM::MOVCCr || MI->getOpcode() == ARM::t2MOVCCr) &&
|
||||||
"Unknown select instruction");
|
"Unknown select instruction");
|
||||||
const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
||||||
MachineInstr *DefMI = canFoldIntoMOVCC(MI->getOperand(2).getReg(), MRI, this);
|
MachineInstr *DefMI = canFoldIntoMOVCC(MI->getOperand(2).getReg(), MRI, this);
|
||||||
bool Invert = !DefMI;
|
bool Invert = !DefMI;
|
||||||
if (!DefMI)
|
if (!DefMI)
|
||||||
|
@ -1714,11 +1714,17 @@ MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI,
|
||||||
if (!DefMI)
|
if (!DefMI)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Find new register class to use.
|
||||||
|
MachineOperand FalseReg = MI->getOperand(Invert ? 2 : 1);
|
||||||
|
unsigned DestReg = MI->getOperand(0).getReg();
|
||||||
|
const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
|
||||||
|
if (!MRI.constrainRegClass(DestReg, PreviousClass))
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Create a new predicated version of DefMI.
|
// Create a new predicated version of DefMI.
|
||||||
// Rfalse is the first use.
|
// Rfalse is the first use.
|
||||||
MachineInstrBuilder NewMI = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
|
MachineInstrBuilder NewMI = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
|
||||||
DefMI->getDesc(),
|
DefMI->getDesc(), DestReg);
|
||||||
MI->getOperand(0).getReg());
|
|
||||||
|
|
||||||
// Copy all the DefMI operands, excluding its (null) predicate.
|
// Copy all the DefMI operands, excluding its (null) predicate.
|
||||||
const MCInstrDesc &DefDesc = DefMI->getDesc();
|
const MCInstrDesc &DefDesc = DefMI->getDesc();
|
||||||
|
@ -1741,7 +1747,6 @@ MachineInstr *ARMBaseInstrInfo::optimizeSelect(MachineInstr *MI,
|
||||||
// register operand tied to the first def.
|
// register operand tied to the first def.
|
||||||
// The tie makes the register allocator ensure the FalseReg is allocated the
|
// The tie makes the register allocator ensure the FalseReg is allocated the
|
||||||
// same register as operand 0.
|
// same register as operand 0.
|
||||||
MachineOperand FalseReg = MI->getOperand(Invert ? 2 : 1);
|
|
||||||
FalseReg.setImplicit();
|
FalseReg.setImplicit();
|
||||||
NewMI.addOperand(FalseReg);
|
NewMI.addOperand(FalseReg);
|
||||||
NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
|
NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
; RUN: llc < %s -march=arm -mcpu=swift -verify-machineinstrs
|
||||||
|
%union.opcode.0.2.5.8.15.28 = type { i32 }
|
||||||
|
|
||||||
|
@opcode = external global %union.opcode.0.2.5.8.15.28, align 4
|
||||||
|
@operands = external hidden global [50 x i8], align 4
|
||||||
|
@.str86 = external hidden unnamed_addr constant [13 x i8], align 1
|
||||||
|
|
||||||
|
; Function Attrs: nounwind ssp
|
||||||
|
define void @xfr() {
|
||||||
|
entry:
|
||||||
|
%bf.load4 = load i32* getelementptr inbounds (%union.opcode.0.2.5.8.15.28* @opcode, i32 0, i32 0), align 4
|
||||||
|
%bf.clear10 = and i32 %bf.load4, 65535
|
||||||
|
%and11 = and i32 %bf.load4, 32768
|
||||||
|
%tobool12 = icmp ne i32 %and11, 0
|
||||||
|
%cond13 = select i1 %tobool12, i32 1073676288, i32 0
|
||||||
|
%or = or i32 %cond13, %bf.clear10
|
||||||
|
%shl = shl nuw i32 %or, 2
|
||||||
|
%add = add i32 0, %shl
|
||||||
|
tail call void (i8*, i32, i32, i8*, ...)* @__sprintf_chk(i8* getelementptr inbounds ([50 x i8]* @operands, i32 0, i32 0), i32 0, i32 50, i8* getelementptr inbounds ([13 x i8]* @.str86, i32 0, i32 0), i32 undef, i32 undef, i32 %add)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @__sprintf_chk(i8*, i32, i32, i8*, ...)
|
Loading…
Reference in New Issue