[llvm] r279969 - Do not use MRI::getMaxLaneMaskForVReg as a mask covering whole register

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 06:15:35 PDT 2016


Author: kparzysz
Date: Mon Aug 29 08:15:35 2016
New Revision: 279969

URL: http://llvm.org/viewvc/llvm-project?rev=279969&view=rev
Log:
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

Added:
    llvm/trunk/test/CodeGen/X86/live-range-nosubreg.ll
Modified:
    llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp
    llvm/trunk/lib/CodeGen/MachineVerifier.cpp

Modified: llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp?rev=279969&r1=279968&r2=279969&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp Mon Aug 29 08:15:35 2016
@@ -66,9 +66,8 @@ void LiveRangeCalc::calculate(LiveInterv
 
     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(LiveRan
     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;
     }

Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=279969&r1=279968&r2=279969&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Mon Aug 29 08:15:35 2016
@@ -1810,19 +1810,18 @@ void MachineVerifier::verifyLiveRangeSeg
     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;

Added: llvm/trunk/test/CodeGen/X86/live-range-nosubreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/live-range-nosubreg.ll?rev=279969&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/live-range-nosubreg.ll (added)
+++ llvm/trunk/test/CodeGen/X86/live-range-nosubreg.ll Mon Aug 29 08:15:35 2016
@@ -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"
+
+ at a = common local_unnamed_addr global i16 0, align 2
+ at c = common global i32 0, align 4
+ at d = common local_unnamed_addr global i8 0, align 1
+ at 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" }




More information about the llvm-commits mailing list