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!");
|
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) {
|
IsDefined = true;
|
||||||
if (*Supers == MO.getReg()) {
|
|
||||||
if (MO.isDef())
|
// If MO is a use of any part of the destination register but is not equal
|
||||||
IsDefined = true;
|
// to OrigDestReg or one of its subregisters, we cannot use SuperDestReg.
|
||||||
else
|
// For example, if OrigDestReg is %al then an implicit use of %ah, %ax,
|
||||||
return false; // SuperReg Imp-used' -> live before the MI
|
// %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)
|
||||||
|
|
|
@ -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
|
||||||
|
...
|
||||||
|
|
Loading…
Reference in New Issue