diff --git a/src/test/java8/ir/com/android/tools/r8/ir/optimize/inliner/SingleCallerInlineOutlineWithNonThrowingPreludeTest.java b/src/test/java8/ir/com/android/tools/r8/ir/optimize/inliner/SingleCallerInlineOutlineWithNonThrowingPreludeTest.java
new file mode 100644
index 0000000..3e90293
--- /dev/null
+++ b/src/test/java8/ir/com/android/tools/r8/ir/optimize/inliner/SingleCallerInlineOutlineWithNonThrowingPreludeTest.java
@@ -0,0 +1,155 @@
+// Copyright (c) 2026, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.ir.optimize.inliner;
+
+import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.codeinspector.AssertUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.android.tools.r8.utils.internal.BooleanUtils;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class SingleCallerInlineOutlineWithNonThrowingPreludeTest extends TestBase {
+
+  @Parameter(0)
+  public boolean allowInliningOfOutlines;
+
+  @Parameter(1)
+  public TestParameters parameters;
+
+  @Parameters(name = "{1}, allow inlining: {0}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build());
+  }
+
+  @Test
+  public void test() throws Exception {
+    AssertUtils.assertFailsCompilationIf(
+        allowInliningOfOutlines,
+        () ->
+            testForR8(parameters)
+                .addInnerClasses(getClass())
+                .addKeepMainRule(Main.class)
+                .addOptionsModification(
+                    options -> {
+                      options.outline.threshold = 2;
+                      options.outline.minSize = 2;
+                      options.getTestingOptions().allowInliningOfOutlines = allowInliningOfOutlines;
+                    })
+                .collectSyntheticItems()
+                .enableInliningAnnotations()
+                .compile()
+                .inspectWithSyntheticItems(
+                    (inspector, syntheticItems) -> {
+                      ClassSubject printerClassSubject = inspector.clazz(Printer.class);
+                      assertThat(printerClassSubject, isPresent());
+
+                      MethodSubject helloMethodSubject =
+                          printerClassSubject.uniqueMethodWithOriginalName("hello");
+                      assertThat(helloMethodSubject, isPresent());
+
+                      MethodSubject worldMethodSubject =
+                          printerClassSubject.uniqueMethodWithOriginalName("world");
+                      assertThat(worldMethodSubject, isPresent());
+
+                      ClassSubject mainClassSubject = inspector.clazz(Main.class);
+                      assertThat(mainClassSubject, isPresent());
+
+                      MethodSubject outlineCandidateMethodSubject =
+                          mainClassSubject.uniqueMethodWithOriginalName("outlineCandidate");
+                      assertThat(outlineCandidateMethodSubject, isPresent());
+
+                      ClassSubject outlineClassSubject =
+                          inspector.clazz(syntheticItems.syntheticOutlineClass(Main.class, 0));
+                      // Note that the outline class is present even when `allowInliningOfOutlines`
+                      // is true, since we do not run another round of tree shaking after the single
+                      // caller inliner pass.
+                      assertThat(outlineClassSubject, isPresent());
+
+                      if (allowInliningOfOutlines) {
+                        assertThat(
+                            outlineCandidateMethodSubject,
+                            allOf(
+                                invokesMethod(helloMethodSubject),
+                                invokesMethod(worldMethodSubject)));
+                      } else {
+                        assertThat(
+                            outlineCandidateMethodSubject,
+                            invokesMethod(outlineClassSubject.uniqueMethod()));
+                      }
+                    })
+                .run(parameters.getRuntime(), Main.class)
+                .assertSuccessWithOutputLines("Hello 3.0, world!"));
+  }
+
+  static class Main {
+
+    static boolean alwaysFalse;
+
+    public static void main(String[] args) {
+      float x = args.length > 0 ? Float.parseFloat(args[0]) : 1.0f;
+      float y = args.length > 1 ? Float.parseFloat(args[1]) : 2.0f;
+      outlineCandidate(x, y);
+
+      // This will be pruned in the primary optimization pass. At this point R8 still does not know
+      // that the `alwaysFalse` field is false.
+      if (alwaysFalse()) {
+        alwaysFalse = true;
+      }
+
+      // This will be pruned in the second optimization pass after the outliner has run. After the
+      // second round of tree shaking, outlineCandidate2() will be removed, and the synthetic
+      // outline will have a single caller.
+      if (alwaysFalse) {
+        outlineCandidate2(x, y);
+      }
+    }
+
+    @NeverInline
+    static boolean alwaysFalse() {
+      return false;
+    }
+
+    @NeverInline
+    static void outlineCandidate(float x, float y) {
+      float z = x + y;
+      Printer.hello(z);
+      Printer.world();
+    }
+
+    @NeverInline
+    static void outlineCandidate2(float x, float y) {
+      float z = x + y;
+      Printer.hello(z);
+      Printer.world();
+    }
+  }
+
+  static class Printer {
+
+    @NeverInline
+    static void hello(float z) {
+      System.out.print("Hello " + z);
+    }
+
+    @NeverInline
+    static void world() {
+      System.out.println(", world!");
+    }
+  }
+}
