[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