mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-04-20 08:26:49 +02:00
81 lines
3.3 KiB
Diff
81 lines
3.3 KiB
Diff
Patch-Source: https://github.com/llvm/llvm-project/commit/398d68f624d667a17727d346a2139a951a1ebce4
|
|
--
|
|
From 398d68f624d667a17727d346a2139a951a1ebce4 Mon Sep 17 00:00:00 2001
|
|
From: Fangrui Song <i@maskray.me>
|
|
Date: Mon, 24 Apr 2023 10:02:06 -0700
|
|
Subject: [PATCH] [PPCMIPeephole] Fix incorrect compare elimination
|
|
|
|
D38236 moves a redundant compare instruction from the loop body to the
|
|
preheader.
|
|
|
|
It has a bug: when `MBB1 == &MBB2`, there may be only one compare instruction in the
|
|
loop. The code will lift the compare instruction to the preheader, failing to
|
|
account for the change of the compare result in a tail call, leading to a miscompile.
|
|
|
|
Suppress the compare elimination to fix https://github.com/llvm/llvm-project/issues/62294
|
|
|
|
Reviewed By: #powerpc, nemanjai
|
|
|
|
Differential Revision: https://reviews.llvm.org/D149030
|
|
---
|
|
llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 5 ++++-
|
|
llvm/test/CodeGen/PowerPC/cmp_elimination.ll | 23 ++++++++++++++++++++
|
|
2 files changed, 27 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
|
|
index b9cb0a29a9511..f1d1d2f3757f6 100644
|
|
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
|
|
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
|
|
@@ -1315,7 +1315,7 @@ static bool eligibleForCompareElimination(MachineBasicBlock &MBB,
|
|
if (isEligibleBB(*Pred1MBB) && isEligibleForMoveCmp(*Pred2MBB)) {
|
|
// We assume Pred1MBB is the BB containing the compare to be merged and
|
|
// Pred2MBB is the BB to which we will append a compare instruction.
|
|
- // Hence we can proceed as is.
|
|
+ // Proceed as is if Pred1MBB is different from MBB.
|
|
}
|
|
else if (isEligibleBB(*Pred2MBB) && isEligibleForMoveCmp(*Pred1MBB)) {
|
|
// We need to swap Pred1MBB and Pred2MBB to canonicalize.
|
|
@@ -1323,6 +1323,9 @@ static bool eligibleForCompareElimination(MachineBasicBlock &MBB,
|
|
}
|
|
else return false;
|
|
|
|
+ if (Pred1MBB == &MBB)
|
|
+ return false;
|
|
+
|
|
// Here, Pred2MBB is the BB to which we need to append a compare inst.
|
|
// We cannot move the compare instruction if operands are not available
|
|
// in Pred2MBB (i.e. defined in MBB by an instruction other than PHI).
|
|
diff --git a/llvm/test/CodeGen/PowerPC/cmp_elimination.ll b/llvm/test/CodeGen/PowerPC/cmp_elimination.ll
|
|
index 56af49f0c267e..871cc5df1f5fb 100644
|
|
--- a/llvm/test/CodeGen/PowerPC/cmp_elimination.ll
|
|
+++ b/llvm/test/CodeGen/PowerPC/cmp_elimination.ll
|
|
@@ -779,6 +779,29 @@ if.end3:
|
|
ret void
|
|
}
|
|
|
|
+;; The result of %cmp may change in a tail call. Don't lift %cmp to the entry block.
|
|
+; CHECK-LABEL: func_tailrecurse:
|
|
+; CHECK-NOT: cmp
|
|
+; CHECK: .LBB{{.*}}:
|
|
+; CHECK: cmplw
|
|
+; CHECK: blt
|
|
+define fastcc zeroext i32 @func_tailrecurse(i32 zeroext %a, i32 zeroext %b) {
|
|
+entry:
|
|
+ br label %tailrecurse
|
|
+
|
|
+tailrecurse: ; preds = %tailrecurse, %entry
|
|
+ %a.tr = phi i32 [ %a, %entry ], [ %b.tr, %tailrecurse ]
|
|
+ %b.tr = phi i32 [ %b, %entry ], [ %a.tr, %tailrecurse ]
|
|
+ %cmp = icmp ult i32 %a.tr, %b.tr
|
|
+ %conv = zext i1 %cmp to i32
|
|
+ %ignore = call signext i32 (i32) @func(i32 %conv)
|
|
+ br i1 %cmp, label %tailrecurse, label %if.end
|
|
+
|
|
+if.end: ; preds = %tailrecurse
|
|
+ %sub = sub nsw i32 %a.tr, %b.tr
|
|
+ ret i32 %sub
|
|
+}
|
|
+
|
|
declare void @dummy1()
|
|
declare void @dummy2()
|
|
declare void @dummy3()
|