[llvm] dc0bbc9 - [IfCvt] Don't use pristine register for counting liveins for predicated instructions.

David Green via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 11 06:46:04 PDT 2021


Author: David Green
Date: 2021-07-11T14:45:54+01:00
New Revision: dc0bbc9d891ab20850761d8d75acc6676754ce2d

URL: https://github.com/llvm/llvm-project/commit/dc0bbc9d891ab20850761d8d75acc6676754ce2d
DIFF: https://github.com/llvm/llvm-project/commit/dc0bbc9d891ab20850761d8d75acc6676754ce2d.diff

LOG: [IfCvt] Don't use pristine register for counting liveins for predicated instructions.

The test case here hits machine verifier problems. There are volatile
long loads that the results of do not get used, loading into two dead
registers. IfCvt will predicate them and as it does will add implicit
uses of the predicating registers due to thinking they are live in. As
nothing has used the register, the machine verifier disagrees that they
are really live and we end up with a failure.

The registers come from Pristine regs that LivePhysRegs counts as live.
This patch adds a addLiveInsNoPristines method to be used instead in
IfCvt, so that only really live in regs need to be added as implicit
operands.

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

Added: 
    llvm/test/CodeGen/ARM/ldrd_ifcvt.ll

Modified: 
    llvm/include/llvm/CodeGen/LivePhysRegs.h
    llvm/lib/CodeGen/IfConversion.cpp
    llvm/lib/CodeGen/LivePhysRegs.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/LivePhysRegs.h b/llvm/include/llvm/CodeGen/LivePhysRegs.h
index 085893462a083..99ba1a28c934b 100644
--- a/llvm/include/llvm/CodeGen/LivePhysRegs.h
+++ b/llvm/include/llvm/CodeGen/LivePhysRegs.h
@@ -133,6 +133,10 @@ class LivePhysRegs {
   /// pristine registers.
   void addLiveIns(const MachineBasicBlock &MBB);
 
+  /// Adds all live-in registers of basic block \p MBB but skips pristine
+  /// registers.
+  void addLiveInsNoPristines(const MachineBasicBlock &MBB);
+
   /// Adds all live-out registers of basic block \p MBB.
   /// Live out registers are the union of the live-in registers of the successor
   /// blocks and pristine registers. Live out registers of the end block are the

diff  --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp
index bb89dca26c5cc..681e2f3dc848b 100644
--- a/llvm/lib/CodeGen/IfConversion.cpp
+++ b/llvm/lib/CodeGen/IfConversion.cpp
@@ -1564,8 +1564,8 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
   if (MRI->tracksLiveness()) {
     // Initialize liveins to the first BB. These are potentially redefined by
     // predicated instructions.
-    Redefs.addLiveIns(CvtMBB);
-    Redefs.addLiveIns(NextMBB);
+    Redefs.addLiveInsNoPristines(CvtMBB);
+    Redefs.addLiveInsNoPristines(NextMBB);
   }
 
   // Remove the branches from the entry so we can add the contents of the true
@@ -1665,8 +1665,8 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
   // predicated instructions.
   Redefs.init(*TRI);
   if (MRI->tracksLiveness()) {
-    Redefs.addLiveIns(CvtMBB);
-    Redefs.addLiveIns(NextMBB);
+    Redefs.addLiveInsNoPristines(CvtMBB);
+    Redefs.addLiveInsNoPristines(NextMBB);
   }
 
   bool HasEarlyExit = CvtBBI->FalseBB != nullptr;
@@ -1828,8 +1828,8 @@ bool IfConverter::IfConvertDiamondCommon(
   //   after tracking the BB1 instructions.
   Redefs.init(*TRI);
   if (MRI->tracksLiveness()) {
-    Redefs.addLiveIns(MBB1);
-    Redefs.addLiveIns(MBB2);
+    Redefs.addLiveInsNoPristines(MBB1);
+    Redefs.addLiveInsNoPristines(MBB2);
   }
 
   // Remove the duplicated instructions at the beginnings of both paths.

diff  --git a/llvm/lib/CodeGen/LivePhysRegs.cpp b/llvm/lib/CodeGen/LivePhysRegs.cpp
index fabaef9ee4d10..c0c7848139e4d 100644
--- a/llvm/lib/CodeGen/LivePhysRegs.cpp
+++ b/llvm/lib/CodeGen/LivePhysRegs.cpp
@@ -239,6 +239,10 @@ void LivePhysRegs::addLiveIns(const MachineBasicBlock &MBB) {
   addBlockLiveIns(MBB);
 }
 
+void LivePhysRegs::addLiveInsNoPristines(const MachineBasicBlock &MBB) {
+  addBlockLiveIns(MBB);
+}
+
 void llvm::computeLiveIns(LivePhysRegs &LiveRegs,
                           const MachineBasicBlock &MBB) {
   const MachineFunction &MF = *MBB.getParent();

diff  --git a/llvm/test/CodeGen/ARM/ldrd_ifcvt.ll b/llvm/test/CodeGen/ARM/ldrd_ifcvt.ll
new file mode 100644
index 0000000000000..e4c92a2c3b1d8
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/ldrd_ifcvt.ll
@@ -0,0 +1,58 @@
+; RUN: llc -mtriple=armv7a-none-eabi %s -o -  -verify-machineinstrs | FileCheck %s
+; RUN: llc -mtriple=thumbv7a-none-eabi %s -o -  -verify-machineinstrs | FileCheck %s
+; RUN: llc -mtriple=thumbv7m-none-eabi %s -o -  -verify-machineinstrs | FileCheck %s
+
+; Check we do not hit verifier errors from ifcvting volatile ldrd's
+; CHECK: ldrdne
+; CHECK: ldrdne
+; CHECK: ldrdne
+; CHECK: ldrdne
+
+define void @c(i64* %b) noreturn nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %land.end.3, %entry
+  %a.0 = phi i32 [ 0, %entry ], [ %conv2.3, %land.end.3 ]
+  %tobool.not = icmp eq i32 %a.0, 0
+  br i1 %tobool.not, label %land.end, label %land.rhs
+
+land.rhs:                                         ; preds = %for.cond
+  %0 = load volatile i64, i64* %b, align 8
+  br label %land.end
+
+land.end:                                         ; preds = %land.rhs, %for.cond
+  %sub.i = add nuw nsw i32 %a.0, 65533
+  %conv2 = and i32 %sub.i, 65535
+  %tobool.not.1 = icmp eq i32 %conv2, 0
+  br i1 %tobool.not.1, label %land.end.1, label %land.rhs.1
+
+land.rhs.1:                                       ; preds = %land.end
+  %1 = load volatile i64, i64* %b, align 8
+  br label %land.end.1
+
+land.end.1:                                       ; preds = %land.rhs.1, %land.end
+  %sub.i.1 = add nuw nsw i32 %a.0, 65530
+  %conv2.1 = and i32 %sub.i.1, 65535
+  %tobool.not.2 = icmp eq i32 %conv2.1, 0
+  br i1 %tobool.not.2, label %land.end.2, label %land.rhs.2
+
+land.rhs.2:                                       ; preds = %land.end.1
+  %2 = load volatile i64, i64* %b, align 8
+  br label %land.end.2
+
+land.end.2:                                       ; preds = %land.rhs.2, %land.end.1
+  %sub.i.2 = add nuw nsw i32 %a.0, 65527
+  %conv2.2 = and i32 %sub.i.2, 65535
+  %tobool.not.3 = icmp eq i32 %conv2.2, 0
+  br i1 %tobool.not.3, label %land.end.3, label %land.rhs.3
+
+land.rhs.3:                                       ; preds = %land.end.2
+  %3 = load volatile i64, i64* %b, align 8
+  br label %land.end.3
+
+land.end.3:                                       ; preds = %land.rhs.3, %land.end.2
+  %sub.i.3 = add nuw nsw i32 %a.0, 65524
+  %conv2.3 = and i32 %sub.i.3, 65535
+  br label %for.cond
+}


        


More information about the llvm-commits mailing list