Do not use MRI::getMaxLaneMaskForVReg as a mask covering whole register

MRI::getMaxLaneMaskForVReg does not always cover the whole register.
For example, on X86 the upper 16 bits of EAX cannot be accessed via
any subregister. Consequently, there is no lane mask that only covers
that part of EAX. The getMaxLaneMaskForVReg will return the union of
the lane masks for all subregisters, and in case of EAX, that union
will not cover the upper 16 bits.

This fixes https://llvm.org/bugs/show_bug.cgi?id=29132

llvm-svn: 279969
This commit is contained in:
Krzysztof Parzyszek 2016-08-29 13:15:35 +00:00
parent 5d3f71f721
commit 0a955d6dcb
3 changed files with 53 additions and 7 deletions

View File

@ -66,9 +66,8 @@ void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
unsigned SubReg = MO.getSubReg();
if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) {
LaneBitmask WholeMask = MRI->getMaxLaneMaskForVReg(Reg);
LaneBitmask SubMask = SubReg != 0 ? TRI.getSubRegIndexLaneMask(SubReg)
: WholeMask;
: MRI->getMaxLaneMaskForVReg(Reg);
// If this is the first time we see a subregister def, initialize
// subranges by creating a copy of the main range.
if (!LI.hasSubRanges() && !LI.empty()) {
@ -177,8 +176,8 @@ void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask Mask,
if (SubReg != 0) {
LaneBitmask SLM = TRI.getSubRegIndexLaneMask(SubReg);
if (MO.isDef())
SLM = MRI->getMaxLaneMaskForVReg(Reg) & ~SLM;
// Ignore uses not covering the current subrange.
SLM = ~SLM;
// Ignore uses not reading the current (sub)range.
if ((SLM & Mask) == 0)
continue;
}

View File

@ -1810,19 +1810,18 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
bool hasRead = false;
bool hasSubRegDef = false;
bool hasDeadDef = false;
LaneBitmask RLM = MRI->getMaxLaneMaskForVReg(Reg);
for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
if (!MOI->isReg() || MOI->getReg() != Reg)
continue;
unsigned Sub = MOI->getSubReg();
LaneBitmask SLM = Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) : RLM;
LaneBitmask SLM = Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) : ~0U;
if (MOI->isDef()) {
if (Sub != 0) {
hasSubRegDef = true;
// An operand vreg0:sub0<def> reads vreg0:sub1..n. Invert the lane
// mask for subregister defs. Read-undef defs will be handled by
// readsReg below.
SLM = ~SLM & RLM;
SLM = ~SLM;
}
if (MOI->isDead())
hasDeadDef = true;

View File

@ -0,0 +1,48 @@
; RUN: llc -march=x86-64 < %s | FileCheck %s
; Check for a sane output. This testcase used to crash. See PR29132.
; CHECK: leal -1
target triple = "x86_64-unknown-linux-gnu"
@a = common local_unnamed_addr global i16 0, align 2
@c = common global i32 0, align 4
@d = common local_unnamed_addr global i8 0, align 1
@b = common global i32 0, align 4
; Function Attrs: norecurse nounwind optsize uwtable
define i32 @main() local_unnamed_addr #0 {
entry:
%0 = load volatile i32, i32* @c, align 4
%tobool = icmp eq i32 %0, 0
%1 = load i16, i16* @a, align 2
br i1 %tobool, label %lor.rhs, label %lor.end
lor.rhs: ; preds = %entry
%inc = add i16 %1, 1
store i16 %inc, i16* @a, align 2
br label %lor.end
lor.end: ; preds = %entry, %lor.rhs
%2 = phi i16 [ %inc, %lor.rhs ], [ %1, %entry ]
%dec = add i16 %2, -1
store i16 %dec, i16* @a, align 2
%3 = load i8, i8* @d, align 1
%sub = sub i8 0, %3
%tobool4 = icmp eq i16 %dec, 0
br i1 %tobool4, label %land.end, label %land.rhs
land.rhs: ; preds = %lor.end
%4 = load volatile i32, i32* @b, align 4
%tobool5 = icmp ne i32 %4, 0
br label %land.end
land.end: ; preds = %lor.end, %land.rhs
%5 = phi i1 [ false, %lor.end ], [ %tobool5, %land.rhs ]
%land.ext = zext i1 %5 to i8
%or = or i8 %land.ext, %sub
store i8 %or, i8* @d, align 1
ret i32 0
}
attributes #0 = { norecurse nounwind optsize uwtable "target-cpu"="x86-64" }