[SystemZ] Proper handling of undef flag while expanding pseudo.
During post-RA pseudo expansion, an 'undef' flag of the source operand should be propagated by emitGRX32Move(). Review: Ulrich Weigand llvm-svn: 292353
This commit is contained in:
parent
197db00e3e
commit
a9bb00d82b
|
@ -131,7 +131,8 @@ void SystemZInstrInfo::expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
|
||||||
MI.setDesc(get(LowOpcodeK));
|
MI.setDesc(get(LowOpcodeK));
|
||||||
else {
|
else {
|
||||||
emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(), DestReg, SrcReg,
|
emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(), DestReg, SrcReg,
|
||||||
SystemZ::LR, 32, MI.getOperand(1).isKill());
|
SystemZ::LR, 32, MI.getOperand(1).isKill(),
|
||||||
|
MI.getOperand(1).isUndef());
|
||||||
MI.setDesc(get(DestIsHigh ? HighOpcode : LowOpcode));
|
MI.setDesc(get(DestIsHigh ? HighOpcode : LowOpcode));
|
||||||
MI.getOperand(1).setReg(DestReg);
|
MI.getOperand(1).setReg(DestReg);
|
||||||
MI.tieOperands(0, 1);
|
MI.tieOperands(0, 1);
|
||||||
|
@ -187,7 +188,7 @@ void SystemZInstrInfo::expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
|
||||||
unsigned Size) const {
|
unsigned Size) const {
|
||||||
emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(),
|
emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(),
|
||||||
MI.getOperand(0).getReg(), MI.getOperand(1).getReg(), LowOpcode,
|
MI.getOperand(0).getReg(), MI.getOperand(1).getReg(), LowOpcode,
|
||||||
Size, MI.getOperand(1).isKill());
|
Size, MI.getOperand(1).isKill(), MI.getOperand(1).isUndef());
|
||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +232,8 @@ void SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MBBI,
|
MachineBasicBlock::iterator MBBI,
|
||||||
const DebugLoc &DL, unsigned DestReg,
|
const DebugLoc &DL, unsigned DestReg,
|
||||||
unsigned SrcReg, unsigned LowLowOpcode,
|
unsigned SrcReg, unsigned LowLowOpcode,
|
||||||
unsigned Size, bool KillSrc) const {
|
unsigned Size, bool KillSrc,
|
||||||
|
bool UndefSrc) const {
|
||||||
unsigned Opcode;
|
unsigned Opcode;
|
||||||
bool DestIsHigh = isHighReg(DestReg);
|
bool DestIsHigh = isHighReg(DestReg);
|
||||||
bool SrcIsHigh = isHighReg(SrcReg);
|
bool SrcIsHigh = isHighReg(SrcReg);
|
||||||
|
@ -243,13 +245,13 @@ void SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB,
|
||||||
Opcode = SystemZ::RISBLH;
|
Opcode = SystemZ::RISBLH;
|
||||||
else {
|
else {
|
||||||
BuildMI(MBB, MBBI, DL, get(LowLowOpcode), DestReg)
|
BuildMI(MBB, MBBI, DL, get(LowLowOpcode), DestReg)
|
||||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
.addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
|
unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
|
||||||
BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
|
BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
|
||||||
.addReg(DestReg, RegState::Undef)
|
.addReg(DestReg, RegState::Undef)
|
||||||
.addReg(SrcReg, getKillRegState(KillSrc))
|
.addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc))
|
||||||
.addImm(32 - Size).addImm(128 + 31).addImm(Rotate);
|
.addImm(32 - Size).addImm(128 + 31).addImm(Rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,7 +816,8 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SystemZ::GRX32BitRegClass.contains(DestReg, SrcReg)) {
|
if (SystemZ::GRX32BitRegClass.contains(DestReg, SrcReg)) {
|
||||||
emitGRX32Move(MBB, MBBI, DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc);
|
emitGRX32Move(MBB, MBBI, DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
|
||||||
|
false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,8 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
|
||||||
void expandLoadStackGuard(MachineInstr *MI) const;
|
void expandLoadStackGuard(MachineInstr *MI) const;
|
||||||
void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
||||||
const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
|
const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
|
||||||
unsigned LowLowOpcode, unsigned Size, bool KillSrc) const;
|
unsigned LowLowOpcode, unsigned Size, bool KillSrc,
|
||||||
|
bool UndefSrc) const;
|
||||||
virtual void anchor();
|
virtual void anchor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
; Test that the backend does not mess up the I/R in case of a use of an undef
|
||||||
|
; register. This typically happens while expanding a pseudo or otherwise
|
||||||
|
; replacing an instruction for another.
|
||||||
|
;
|
||||||
|
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -verify-machineinstrs \
|
||||||
|
; RUN: |& FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
|
; LLCRMux
|
||||||
|
define void @f1(i8*) {
|
||||||
|
; CHECK-LABEL: f1:
|
||||||
|
; CHECK-NOT: *** Bad machine code: Using an undefined physical register ***
|
||||||
|
BB:
|
||||||
|
%L5 = load i8, i8* %0
|
||||||
|
%B9 = lshr i8 %L5, -1
|
||||||
|
br label %CF
|
||||||
|
|
||||||
|
CF: ; preds = %CF, %BB
|
||||||
|
%Cmp25 = icmp ne i8 27, %B9
|
||||||
|
br i1 %Cmp25, label %CF, label %CF34
|
||||||
|
|
||||||
|
CF34: ; preds = %CF
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue