[llvm] [InstCombine] Fix crash on dereferencing null insertion point (PR #216363)

Hendrik Hübner via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 10:47:02 PDT 2026


https://github.com/HendrikHuebner updated https://github.com/llvm/llvm-project/pull/216363

>From 050f0025725712f7cc5f4bf38aba1b51809312b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <hhuebner at hhuebnerMacBookPro.local>
Date: Fri, 14 Aug 2026 18:49:56 +0200
Subject: [PATCH 1/3] [InstCombine] Assert on missing inversion insertion point

---
 .../Transforms/InstCombine/InstCombineAndOrXor.cpp  | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b6f4a55c07e8a..7757ce2e2c389 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4996,14 +4996,18 @@ static Instruction *canonicalizeAbs(BinaryOperator &Xor,
 static bool canFreelyInvert(InstCombiner &IC, Value *Op,
                             Instruction *IgnoredUser) {
   auto *I = dyn_cast<Instruction>(Op);
-  return I && IC.isFreeToInvert(I, /*WillInvertAllUses=*/true) &&
+  return I && I->getInsertionPointAfterDef() &&
+         IC.isFreeToInvert(I, /*WillInvertAllUses=*/true) &&
          IC.canFreelyInvertAllUsersOf(I, IgnoredUser);
 }
 
 static Value *freelyInvert(InstCombinerImpl &IC, Value *Op,
                            Instruction *IgnoredUser) {
   auto *I = cast<Instruction>(Op);
-  IC.Builder.SetInsertPoint(*I->getInsertionPointAfterDef());
+  auto InsertPt = I->getInsertionPointAfterDef();
+  assert(InsertPt &&
+         "freelyInvert requires an instruction with a valid insertion point");
+  IC.Builder.SetInsertPoint(*InsertPt);
   Value *NotOp = IC.Builder.CreateNot(Op, Op->getName() + ".not");
   Op->replaceUsesWithIf(NotOp,
                         [NotOp](Use &U) { return U.getUser() != NotOp; });
@@ -5047,7 +5051,10 @@ bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
   Op0 = freelyInvert(*this, Op0, &I);
   Op1 = freelyInvert(*this, Op1, &I);
 
-  Builder.SetInsertPoint(*I.getInsertionPointAfterDef());
+  auto InsertPt = I.getInsertionPointAfterDef();
+  assert(InsertPt &&
+         "sinkNotIntoLogicalOp requires an instruction with a valid insertion point");
+  Builder.SetInsertPoint(*InsertPt);
   Value *NewLogicOp;
   if (IsBinaryOp) {
     NewLogicOp = Builder.CreateBinOp(NewOpc, Op0, Op1, I.getName() + ".not");

>From d1c5bb99e3db6e6227a7424b77b88a4fa4d30576 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <hhuebner at hhuebnerMacBookPro.local>
Date: Fri, 14 Aug 2026 19:34:03 +0200
Subject: [PATCH 2/3] fmt and test

---
 .../InstCombine/InstCombineAndOrXor.cpp       |  4 ++--
 .../Transforms/InstCombine/free-inversion.ll  | 24 +++++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 7757ce2e2c389..b9352b32a4c7b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -5052,8 +5052,8 @@ bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
   Op1 = freelyInvert(*this, Op1, &I);
 
   auto InsertPt = I.getInsertionPointAfterDef();
-  assert(InsertPt &&
-         "sinkNotIntoLogicalOp requires an instruction with a valid insertion point");
+  assert(InsertPt && "sinkNotIntoLogicalOp requires an instruction with a "
+		     "valid insertion point");
   Builder.SetInsertPoint(*InsertPt);
   Value *NewLogicOp;
   if (IsBinaryOp) {
diff --git a/llvm/test/Transforms/InstCombine/free-inversion.ll b/llvm/test/Transforms/InstCombine/free-inversion.ll
index 2e8e75c3ab3ef..ea1b27ff9efdd 100644
--- a/llvm/test/Transforms/InstCombine/free-inversion.ll
+++ b/llvm/test/Transforms/InstCombine/free-inversion.ll
@@ -760,3 +760,27 @@ define i64 @PR71390(i64 %v) {
   %not5 = xor i64 %and4, -1
   ret i64 %not5
 }
+
+define i1 @freely_invert_catchswitch(i8 %x) personality ptr null {
+; CHECK-LABEL: @freely_invert_catchswitch(
+; CHECK:       d:
+; CHECK-NEXT:    [[NOTP:%.*]] = phi i1 [ false, [[N:%.*]] ], [ true, [[E:%.*]] ]
+; CHECK-NEXT:    [[S:%.*]] = catchswitch within none [label %c] unwind to caller
+;
+e:
+  invoke void @use.i1(i1 true) to label %n unwind label %d
+n:
+  invoke void @use.i1(i1 true) to label %ret unwind label %d
+ret:
+  ret i1 false
+d:
+  %p = phi i1 [ true, %n ], [ false, %e ]
+  %s = catchswitch within none [label %c] unwind to caller
+c:
+  catchpad within %s [ptr null]
+  %z = icmp eq i8 %x, 0
+  %y = select i1 %p, i1 %z, i1 false
+  %w = xor i1 %y, true
+  call void @llvm.assume(i1 %w)
+  ret i1 false
+}

>From 83f059ebdb98c83a7f617e32111b2cf6529fcf97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <hhuebner at hhuebnerMacBookPro.local>
Date: Fri, 14 Aug 2026 19:46:50 +0200
Subject: [PATCH 3/3] fmt

---
 llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b9352b32a4c7b..7bc0d7d2f11b8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -5053,7 +5053,7 @@ bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
 
   auto InsertPt = I.getInsertionPointAfterDef();
   assert(InsertPt && "sinkNotIntoLogicalOp requires an instruction with a "
-		     "valid insertion point");
+                     "valid insertion point");
   Builder.SetInsertPoint(*InsertPt);
   Value *NewLogicOp;
   if (IsBinaryOp) {



More information about the llvm-commits mailing list