forked from OSchip/llvm-project
[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:
parent
a9d2e004d2
commit
c560a18c7f
|
@ -249,15 +249,16 @@ bool FixupBWInstPass::getSuperRegDestIfDead(MachineInstr *OrigMI,
|
|||
|
||||
assert((MO.isDef() || MO.isUse()) && "Expected Def or Use only!");
|
||||
|
||||
for (MCSuperRegIterator Supers(OrigDestReg, TRI, true); Supers.isValid();
|
||||
++Supers) {
|
||||
if (*Supers == MO.getReg()) {
|
||||
if (MO.isDef())
|
||||
IsDefined = true;
|
||||
else
|
||||
return false; // SuperReg Imp-used' -> live before the MI
|
||||
}
|
||||
}
|
||||
if (MO.isDef() && TRI->isSuperRegisterEq(OrigDestReg, MO.getReg()))
|
||||
IsDefined = true;
|
||||
|
||||
// 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.
|
||||
if (!IsDefined)
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
%t2 = or i16 undef, %t1
|
||||
ret i16 %t2
|
||||
}
|
||||
|
||||
define void @test5() {ret void}
|
||||
...
|
||||
---
|
||||
# CHECK-LABEL: name: test1
|
||||
|
@ -199,3 +201,46 @@ body: |
|
|||
%ax = OR16rr undef %ax, %r9w, implicit-def %eflags
|
||||
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
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue