[PATCH] D149030: [PPCMIPeephole] Fix incorrect compare elimination

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 23 13:33:43 PDT 2023


MaskRay created this revision.
MaskRay added reviewers: PowerPC, nemanjai.
Herald added subscribers: shchenz, kbarton, hiraditya.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

D38236 <https://reviews.llvm.org/D38236> moves a redundant compare instruction from the loop body to the
preheader.

It has a bug: when `MBB1 == &MBB2`, there is 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, leading to a miscompile.

Suppress the compare elimination to fix https://github.com/llvm/llvm-project/issues/62294


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149030

Files:
  llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
  llvm/test/CodeGen/PowerPC/cmp_elimination.ll


Index: llvm/test/CodeGen/PowerPC/cmp_elimination.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/cmp_elimination.ll
+++ llvm/test/CodeGen/PowerPC/cmp_elimination.ll
@@ -779,6 +779,29 @@
   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()
Index: llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -1315,7 +1315,7 @@
     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 @@
     }
     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).


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149030.516203.patch
Type: text/x-patch
Size: 2195 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230423/9b89f1aa/attachment.bin>


More information about the llvm-commits mailing list