[llvm] [IPSCCP] Do not attempt `tryToReplaceWithConstant` if may break invariants (PR #102820)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 11 08:55:36 PDT 2024


https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/102820

If the call base is not marked as `willreturn`, do not attempt replacing the return value with constant, as otherwise it may lead to redundant instructions for recomputing the constant in codegen (as exhibited in https://github.com/llvm/llvm-project/issues/102791) – amongst other things.

I'm not sure why we should `tryToReplaceWithConstant` if the call base is non-removable and the function would be called nonetheless, in the first place; although just checking for `!canRemoveInstruction(CB)` leads to 36 test failures in SCCP.

Test updates / test addition to be done once confirmed this is the correct direction to pursue. 

>From 5e903d7f4ebf7e4fa2232d57c94613f7f76b76b7 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sun, 11 Aug 2024 17:38:28 +0200
Subject: [PATCH] [IPSCCP] Do not `tryToReplaceWithConstant` if may break
 invariants

---
 llvm/lib/Transforms/Utils/SCCPSolver.cpp | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index c944859cc69b8..8b4f3982ef4a8 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -69,12 +69,13 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
   Constant *Const = getConstantOrNull(V);
   if (!Const)
     return false;
-  // Replacing `musttail` instructions with constant breaks `musttail` invariant
-  // unless the call itself can be removed.
-  // Calls with "clang.arc.attachedcall" implicitly use the return value and
-  // those uses cannot be updated with a constant.
+
+  // Replacing call ret values with constant may break some invariants, unless
+  // the call itself can be removed. Calls with "clang.arc.attachedcall"
+  // implicitly use the return value and those uses cannot be updated with a
+  // constant.
   CallBase *CB = dyn_cast<CallBase>(V);
-  if (CB && ((CB->isMustTailCall() &&
+  if (CB && (((CB->isMustTailCall() || !CB->willReturn()) &&
               !canRemoveInstruction(CB)) ||
              CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall))) {
     Function *F = CB->getCalledFunction();



More information about the llvm-commits mailing list