[X86FixupBWInsts] Fix miscompilation if sibling sub-register is live.

Summary: The issues was found during D40524.

Reviewers: andrew.w.kaylor, craig.topper, MatzeB

Reviewed By: andrew.w.kaylor

Subscribers: aivchenk, llvm-commits

Differential Revision: https://reviews.llvm.org/D42533

llvm-svn: 323635
This commit is contained in:
Andrei Elovikov 2018-01-29 09:26:04 +00:00
parent a9d2e004d2
commit c560a18c7f
2 changed files with 55 additions and 9 deletions

View File

@ -249,15 +249,16 @@ bool FixupBWInstPass::getSuperRegDestIfDead(MachineInstr *OrigMI,
assert((MO.isDef() || MO.isUse()) && "Expected Def or Use only!"); assert((MO.isDef() || MO.isUse()) && "Expected Def or Use only!");
for (MCSuperRegIterator Supers(OrigDestReg, TRI, true); Supers.isValid(); if (MO.isDef() && TRI->isSuperRegisterEq(OrigDestReg, MO.getReg()))
++Supers) {
if (*Supers == MO.getReg()) {
if (MO.isDef())
IsDefined = true; IsDefined = true;
else
return false; // SuperReg Imp-used' -> live before the MI // If MO is a use of any part of the destination register but is not equal
} // to OrigDestReg or one of its subregisters, we cannot use SuperDestReg.
} // For example, if OrigDestReg is %al then an implicit use of %ah, %ax,
// %eax, or %rax will prevent us from using the %eax register.
if (MO.isUse() && !TRI->isSubRegisterEq(OrigDestReg, MO.getReg()) &&
TRI->regsOverlap(SuperDestReg, MO.getReg()))
return false;
} }
// Reg is not Imp-def'ed -> it's live both before/after the instruction. // Reg is not Imp-def'ed -> it's live both before/after the instruction.
if (!IsDefined) if (!IsDefined)

View File

@ -32,6 +32,8 @@
%t2 = or i16 undef, %t1 %t2 = or i16 undef, %t1
ret i16 %t2 ret i16 %t2
} }
define void @test5() {ret void}
... ...
--- ---
# CHECK-LABEL: name: test1 # CHECK-LABEL: name: test1
@ -199,3 +201,46 @@ body: |
%ax = OR16rr undef %ax, %r9w, implicit-def %eflags %ax = OR16rr undef %ax, %r9w, implicit-def %eflags
RETQ %ax RETQ %ax
... ...
---
# CHECK-LABEL: name: test5
name: test5
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
liveins:
- { reg: '%ch', reg: '%bl' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
stack:
constants:
body: |
bb.0:
successors:
liveins: %ch, %bl
%cl = MOV8rr %bl, implicit-def %cx, implicit killed %ch, implicit-def %eflags
; CHECK: %cl = MOV8rr %bl, implicit-def %cx, implicit killed %ch, implicit-def %eflags
RETQ %cx
...