[llvm] a455c91 - llvm-reduce: Add reduction for invokes

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 3 14:04:39 PST 2023


Author: Matt Arsenault
Date: 2023-01-03T17:03:44-05:00
New Revision: a455c91601a87c2452a3199a0df8390130a28e90

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

LOG: llvm-reduce: Add reduction for invokes

Main thing I was unsure about was to whether try to delete the now
dead landing blocks, or leave that for the unreachable block reduction.

Personality function is not reduced, but that should be a separate
reduction on the function.

Fixes #58815

Added: 
    llvm/test/tools/llvm-reduce/reduce-invoke.ll
    llvm/tools/llvm-reduce/deltas/ReduceInvokes.cpp
    llvm/tools/llvm-reduce/deltas/ReduceInvokes.h

Modified: 
    llvm/tools/llvm-reduce/CMakeLists.txt
    llvm/tools/llvm-reduce/DeltaManager.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-reduce/reduce-invoke.ll b/llvm/test/tools/llvm-reduce/reduce-invoke.ll
new file mode 100644
index 000000000000..73917a6b3c73
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/reduce-invoke.ll
@@ -0,0 +1,129 @@
+; Test the invoke reduction standalone, dead blocks are not removed
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=invokes --test FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s --test-arg --input-file %s -o %t.0
+; RUN: FileCheck --check-prefixes=CHECK,RESULT,RESULT-SINGLE %s < %t.0
+
+; Test the full reduction pipeline, which cleans up unreachable blocks
+; RUN: llvm-reduce --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s --test-arg --input-file %s -o %t.1
+; RUN: FileCheck --check-prefixes=CHECK,RESULT,RESULT-FULL %s < %t.1
+
+
+define i32 @maybe_throwing_callee(i32 %arg) {
+  call void @thrown()
+  ret i32 %arg
+}
+
+declare void @did_not_throw(i32)
+
+declare void @thrown()
+
+; CHECK-LABEL: define void @invoke_keep_landingpad_block(i32 %arg) personality ptr @__gxx_personality_v0 {
+; INTERESTING: i32 @maybe_throwing_callee(
+
+; RESULT-SINGLE: %i0 = call i32 @maybe_throwing_callee(i32 %arg), !some.metadata !0
+; RESULT-SINGLE-NEXT: br label %bb3
+
+; RESULT-FULL: %i0 = call i32 @maybe_throwing_callee()
+; RESULT-FULL-NEXT: br label %bb4
+
+
+; RESULT-SINGLE: bb1:  ; No predecessors!
+; RESULT-SINGLE-NEXT: %landing = landingpad { ptr, i32 }
+; RESULT-SINGLE-NEXT: catch ptr null
+; RESULT-SINGLE-NEXT: call void @thrown()
+define void @invoke_keep_landingpad_block(i32 %arg) personality ptr @__gxx_personality_v0 {
+bb:
+  %i0 = invoke i32 @maybe_throwing_callee(i32 %arg)
+          to label %bb3 unwind label %bb1, !some.metadata !0
+
+bb1:                                              ; preds = %bb
+  %landing = landingpad { ptr, i32 }
+          catch ptr null
+  ; INTERESTING: call void @thrown()
+  call void @thrown()
+  br label %bb4
+
+bb3:                                              ; preds = %bb
+  call void @did_not_throw(i32 %i0)
+  br label %bb4
+
+bb4:                                              ; preds = %bb3, %bb1
+  ret void
+}
+
+; CHECK-LABEL: define void @invoke_drop_landingpad_block(i32 %arg) personality ptr @__gxx_personality_v0 {
+; INTERESTING: i32 @maybe_throwing_callee(
+
+; RESULT-SINGLE: %i0 = call i32 @maybe_throwing_callee(i32 %arg), !some.metadata !0
+; RESULT-SINGLE-NEXT: br label %bb3
+
+; RESULT-SINGLE: bb1:  ; No predecessors!
+; RESULT-SINGLE-NEXT: %landing = landingpad { ptr, i32 }
+
+; RESULT-SINGLE: bb3:
+; RESULT-SINGLE-NEXT: call void @did_not_throw(i32 %i0)
+
+; RESULT-FULL: %i0 = call i32 @maybe_throwing_callee()
+; RESULT-FULL-NEXT: call void @did_not_throw()
+; RESULT-FULL-NEXT: ret void
+define void @invoke_drop_landingpad_block(i32 %arg) personality ptr @__gxx_personality_v0 {
+bb:
+  %i0 = invoke i32 @maybe_throwing_callee(i32 %arg)
+          to label %bb3 unwind label %bb1, !some.metadata !0
+
+bb1:                                              ; preds = %bb
+  %landing = landingpad { ptr, i32 }
+          catch ptr null
+  call void @thrown()
+  br label %bb4
+
+bb3:                                              ; preds = %bb
+  ; INTERESTING: call void @did_not_throw(
+  call void @did_not_throw(i32 %i0)
+  br label %bb4
+
+bb4:                                              ; preds = %bb3, %bb1
+  ret void
+}
+
+declare i32 @another_maybe_throwing_callee(i32 %arg)
+
+; Test the same landing pad block is used by multiple invokes
+; CHECK-LABEL: define i32 @multi_invoke_caller(i32 %arg) personality ptr @__gxx_personality_v0 {
+define i32 @multi_invoke_caller(i32 %arg) personality ptr @__gxx_personality_v0 {
+bb:
+  %i0 = invoke i32 @maybe_throwing_callee(i32 %arg)
+          to label %bb3 unwind label %bb1, !some.metadata !0
+
+; RESULT: bb1:                                              ; preds = %bb4
+; RESULT-NEXT: %landing = landingpad { ptr, i32 }
+; RESULT-NEXT:   catch ptr null
+bb1:                                              ; preds = %bb
+  %landing = landingpad { ptr, i32 }
+          catch ptr null
+  ; INTERESTING: call void @thrown()
+  call void @thrown()
+  br label %bb4
+
+bb3:                                              ; preds = %bb
+  call void @did_not_throw(i32 %i0)
+  br label %bb4
+
+bb4:                                              ; preds = %bb3, %bb1
+  ; INTERESTING: invoke i32 @another_maybe_throwing_callee(
+
+  ; RESULT-SINGLE:   %i1 = invoke i32 @another_maybe_throwing_callee(i32 %arg)
+  ; RESULT-SINGLE-NEXT: to label %bb5 unwind label %bb1, !some.metadata !1
+
+  ; RESULT-FULL:   %i1 = invoke i32 @another_maybe_throwing_callee(i32 0)
+  ; RESULT-FULL-NEXT: to label %bb5 unwind label %bb1{{$}}
+  %i1 = invoke i32 @another_maybe_throwing_callee(i32 %arg)
+          to label %bb5 unwind label %bb1, !some.metadata !1
+
+bb5:
+  ret i32 %i1
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+!0 = !{!"arst"}
+!1 = !{!"arstarst"}

diff  --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt
index 66ebf589248c..b1e8fecca506 100644
--- a/llvm/tools/llvm-reduce/CMakeLists.txt
+++ b/llvm/tools/llvm-reduce/CMakeLists.txt
@@ -38,6 +38,7 @@ add_llvm_tool(llvm-reduce
   deltas/ReduceGlobalVars.cpp
   deltas/ReduceInstructions.cpp
   deltas/ReduceInstructionFlags.cpp
+  deltas/ReduceInvokes.cpp
   deltas/ReduceMetadata.cpp
   deltas/ReduceModuleData.cpp
   deltas/ReduceMemoryOperations.cpp

diff  --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 2ebadd0ce62f..57e8175f1957 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -31,6 +31,7 @@
 #include "deltas/ReduceInstructionFlagsMIR.h"
 #include "deltas/ReduceInstructions.h"
 #include "deltas/ReduceInstructionsMIR.h"
+#include "deltas/ReduceInvokes.h"
 #include "deltas/ReduceMemoryOperations.h"
 #include "deltas/ReduceMetadata.h"
 #include "deltas/ReduceModuleData.h"
@@ -76,6 +77,7 @@ static cl::list<std::string>
     DELTA_PASS("aliases", reduceAliasesDeltaPass)                              \
     DELTA_PASS("simplify-conditionals-true", reduceConditionalsTrueDeltaPass)  \
     DELTA_PASS("simplify-conditionals-false", reduceConditionalsFalseDeltaPass)\
+    DELTA_PASS("invokes", reduceInvokesDeltaPass)                              \
     DELTA_PASS("unreachable-basic-blocks", reduceUnreachableBasicBlocksDeltaPass) \
     DELTA_PASS("basic-blocks", reduceBasicBlocksDeltaPass)                     \
     DELTA_PASS("simplify-cfg", reduceUsingSimplifyCFGDeltaPass)                \

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceInvokes.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInvokes.cpp
new file mode 100644
index 000000000000..7c7d94ba1fbf
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceInvokes.cpp
@@ -0,0 +1,39 @@
+//===- ReduceInvokes.cpp - Specialized Delta Pass -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Try to replace invokes with calls.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceInvokes.h"
+#include "Delta.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Transforms/Utils/Local.h"
+
+static void reduceInvokesInFunction(Oracle &O, Function &F) {
+  for (BasicBlock &BB : F) {
+    InvokeInst *Invoke = dyn_cast<InvokeInst>(BB.getTerminator());
+    if (Invoke && !O.shouldKeep())
+      changeToCall(Invoke);
+  }
+
+  // TODO: We most likely are leaving behind dead landingpad blocks. Should we
+  // delete unreachable blocks now, or leave that for the unreachable block
+  // reduction.
+}
+
+static void reduceInvokesInModule(Oracle &O, Module &Mod) {
+  for (Function &F : Mod) {
+    if (F.hasPersonalityFn())
+      reduceInvokesInFunction(O, F);
+  }
+}
+
+void llvm::reduceInvokesDeltaPass(TestRunner &Test) {
+  runDeltaPass(Test, reduceInvokesInModule, "Reducing Invokes");
+}

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceInvokes.h b/llvm/tools/llvm-reduce/deltas/ReduceInvokes.h
new file mode 100644
index 000000000000..9607add16600
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceInvokes.h
@@ -0,0 +1,18 @@
+//===- ReduceInvokes.h - Specialized Delta Pass -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEINVOKES_H
+#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEINVOKES_H
+
+#include "TestRunner.h"
+
+namespace llvm {
+void reduceInvokesDeltaPass(TestRunner &Test);
+} // namespace llvm
+
+#endif


        


More information about the llvm-commits mailing list