[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:
Jonas Paulsson 2017-01-18 08:32:54 +00:00
parent 197db00e3e
commit a9bb00d82b
3 changed files with 35 additions and 7 deletions

View File

@ -131,7 +131,8 @@ void SystemZInstrInfo::expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
MI.setDesc(get(LowOpcodeK));
else {
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.getOperand(1).setReg(DestReg);
MI.tieOperands(0, 1);
@ -187,7 +188,7 @@ void SystemZInstrInfo::expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
unsigned Size) const {
emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(),
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();
}
@ -231,7 +232,8 @@ void SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, unsigned DestReg,
unsigned SrcReg, unsigned LowLowOpcode,
unsigned Size, bool KillSrc) const {
unsigned Size, bool KillSrc,
bool UndefSrc) const {
unsigned Opcode;
bool DestIsHigh = isHighReg(DestReg);
bool SrcIsHigh = isHighReg(SrcReg);
@ -243,13 +245,13 @@ void SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB,
Opcode = SystemZ::RISBLH;
else {
BuildMI(MBB, MBBI, DL, get(LowLowOpcode), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
.addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc));
return;
}
unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
.addReg(DestReg, RegState::Undef)
.addReg(SrcReg, getKillRegState(KillSrc))
.addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc))
.addImm(32 - Size).addImm(128 + 31).addImm(Rotate);
}
@ -814,7 +816,8 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
}
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;
}

View File

@ -151,7 +151,8 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
void expandLoadStackGuard(MachineInstr *MI) const;
void emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
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();
protected:

View File

@ -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
}