[llvm] [SelectOptimize] Reject Not as BinOp SelectLike aux (fix #226417) (PR #226539)
Atharva Ajmera via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 26 02:01:54 PDT 2026
https://github.com/atharvaajmera updated https://github.com/llvm/llvm-project/pull/226539
>From 163aff05b390a2ad0a1c511bcfdd050bd9a24c0f Mon Sep 17 00:00:00 2001
From: atharvaajmera <atharvaajmera06 at gmail.com>
Date: Fri, 25 Sep 2026 22:35:02 +0530
Subject: [PATCH] [SelectOptimize] Reject Not as BinOp SelectLike aux (fix
#226417)
getTrueOrFalseValue() only supports ZExt, SExt, and Shift auxiliaries for BinOp SelectLikes. Skip other auxiliary kinds (such as Not/xor) when forming BinOp groups to prevent hitting an unexpected opcode assertion during conversion.
Fixes #226417
---
llvm/lib/CodeGen/SelectOptimize.cpp | 5 ++
.../CodeGen/AArch64/selectopt-issue226417.ll | 81 +++++++++++++++++++
2 files changed, 86 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/selectopt-issue226417.ll
diff --git a/llvm/lib/CodeGen/SelectOptimize.cpp b/llvm/lib/CodeGen/SelectOptimize.cpp
index ac2ebcc620051e..95c4dbad4a4a89 100644
--- a/llvm/lib/CodeGen/SelectOptimize.cpp
+++ b/llvm/lib/CodeGen/SelectOptimize.cpp
@@ -884,6 +884,11 @@ void SelectOptimizeImpl::collectSelectGroups(BasicBlock &BB,
auto *Op = I->getOperand(Idx);
auto It = SelectInfo.find(Op);
if (It != SelectInfo.end() && It->second.IsAuxiliary) {
+ // getTrueOrFalseValue only supports ZExt, SExt, and Shift auxiliaries for BinOps.
+ auto *OpI = dyn_cast<Instruction>(Op);
+ if (!OpI || (!isa<ZExtInst>(OpI) && !isa<SExtInst>(OpI) &&
+ !isa<LShrOperator>(OpI) && !isa<AShrOperator>(OpI)))
+ continue;
Cond = It->second.Cond;
bool Inverted = It->second.IsInverted;
return SelectInfo.insert({I, {Cond, false, Inverted, Idx}}).first;
diff --git a/llvm/test/CodeGen/AArch64/selectopt-issue226417.ll b/llvm/test/CodeGen/AArch64/selectopt-issue226417.ll
new file mode 100644
index 00000000000000..a4e7dd70b256ac
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/selectopt-issue226417.ll
@@ -0,0 +1,81 @@
+; RUN: opt -passes='require<profile-summary>,function(select-optimize)' -mtriple=aarch64-linux-gnu -mcpu=generic -S < %s | FileCheck %s
+
+; Test that xor auxiliaries are not grouped into BinOp SelectLikes (#226417).
+
+define void @not_xor_add_not_selectlike(i32 %n, i1 %c, i1 %v, i32 %a, i32 %b) {
+; CHECK-LABEL: @not_xor_add_not_selectlike(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[OUTER:%.*]]
+; CHECK: outer:
+; CHECK: latch:
+; CHECK-NEXT: [[NC:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[SH:%.*]] = lshr i1 [[V:%.*]], 0
+; CHECK-NEXT: [[S0:%.*]] = select i1 [[C]], i32 [[A:%.*]], i32 [[B:%.*]]
+; CHECK-NEXT: [[ADD:%.*]] = add i1 [[NC]], [[SH]]
+; CHECK-NEXT: [[S2:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]]
+; CHECK-NOT: select.end
+; CHECK-NOT: freeze
+;
+entry:
+ br label %outer
+
+outer:
+ %i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
+ br label %inner
+
+inner:
+ %j = phi i32 [ 0, %outer ], [ %j.next, %inner ]
+ %j.next = add i32 %j, 1
+ %ic = icmp slt i32 %j.next, %n
+ br i1 %ic, label %inner, label %latch
+
+latch:
+ %nc = xor i1 %c, true
+ %sh = lshr i1 %v, 0
+ %s0 = select i1 %c, i32 %a, i32 %b
+ %add = add i1 %nc, %sh
+ %s2 = select i1 %c, i32 %a, i32 %b
+ %i.next = add i32 %i, 1
+ %oc = icmp slt i32 %i.next, %n
+ br i1 %oc, label %outer, label %exit
+
+exit:
+ ret void
+}
+
+define void @not_xor_sub_not_selectlike(i32 %n, i1 %c, i1 %v, i32 %a, i32 %b) {
+; CHECK-LABEL: @not_xor_sub_not_selectlike(
+; CHECK: latch:
+; CHECK-NEXT: [[NC:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[SH:%.*]] = lshr i1 [[V:%.*]], 0
+; CHECK-NEXT: [[SUB:%.*]] = sub i1 [[SH]], [[NC]]
+; CHECK-NEXT: [[S0:%.*]] = select i1 [[C]], i32 [[A:%.*]], i32 [[B:%.*]]
+; CHECK-NEXT: [[S2:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]]
+; CHECK-NOT: select.end
+;
+entry:
+ br label %outer
+
+outer:
+ %i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
+ br label %inner
+
+inner:
+ %j = phi i32 [ 0, %outer ], [ %j.next, %inner ]
+ %j.next = add i32 %j, 1
+ %ic = icmp slt i32 %j.next, %n
+ br i1 %ic, label %inner, label %latch
+
+latch:
+ %nc = xor i1 %c, true
+ %sh = lshr i1 %v, 0
+ %sub = sub i1 %sh, %nc
+ %s0 = select i1 %c, i32 %a, i32 %b
+ %s2 = select i1 %c, i32 %a, i32 %b
+ %i.next = add i32 %i, 1
+ %oc = icmp slt i32 %i.next, %n
+ br i1 %oc, label %outer, label %exit
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list