[llvm-branch-commits] [llvm] [AArch64][TTI] Drop single-use requirement on the mask from BSL sinking (PR #232786)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Oct 16 07:59:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Valeriy Savchenko (SavchenkoValeriy)
<details>
<summary>Changes</summary>
Drop the one-use requirement on the mask's Not. Sinking puts a copy of the
Not next to the And, and the original stays for its other users.
ISel can then form bsl/bif even when the Not has other uses.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Full diff: https://github.com/llvm/llvm-project/pull/232786.diff
3 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+3-3)
- (modified) llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll (+44)
- (modified) llvm/test/Transforms/CodeGenPrepare/AArch64/sink-free-instructions.ll (+36)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 1c70822130fc6..a557d612a0077 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -3332,9 +3332,9 @@ static std::optional<Instruction *> instCombineSVESDIV(InstCombiner &IC,
static bool matchBSL(const Instruction *I, Instruction *&MainAnd,
Instruction *&OtherAnd, Value *&A, Value *&B) {
Value *MaskValue;
- if (!match(I, m_c_Or(m_OneUse(m_Instruction(OtherAnd)),
- m_OneUse(m_c_And(m_OneUse(m_Not(m_Value(MaskValue))),
- m_Value(A))))))
+ if (!match(I,
+ m_c_Or(m_OneUse(m_Instruction(OtherAnd)),
+ m_OneUse(m_c_And(m_Not(m_Value(MaskValue)), m_Value(A))))))
return false;
if (!match(OtherAnd, m_c_And(m_Specific(MaskValue), m_Value(B))))
diff --git a/llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll b/llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll
index 0dcd4bb159460..01bb811051ed5 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-bit-gen.ll
@@ -318,3 +318,47 @@ if.then:
if.else:
ret <8 x i8> %b
}
+
+define <8 x i8> @test_bit_sink_not_after_splat_not_multiuse(<8 x i8> %m, <8 x i8> %b, i8 %s, i1 %c, ptr %p) {
+; CHECK-SD-LABEL: test_bit_sink_not_after_splat_not_multiuse:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: tbz w1, #0, .LBB13_2
+; CHECK-SD-NEXT: // %bb.1: // %if.then
+; CHECK-SD-NEXT: dup v2.8b, w0
+; CHECK-SD-NEXT: mvn v2.8b, v2.8b
+; CHECK-SD-NEXT: bsl v0.8b, v1.8b, v2.8b
+; CHECK-SD-NEXT: str d0, [x2]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .LBB13_2:
+; CHECK-SD-NEXT: mvn v0.8b, v0.8b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: test_bit_sink_not_after_splat_not_multiuse:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: tbz w1, #0, .LBB13_2
+; CHECK-GI-NEXT: // %bb.1: // %if.then
+; CHECK-GI-NEXT: mvn w8, w0
+; CHECK-GI-NEXT: dup v2.8b, w8
+; CHECK-GI-NEXT: bsl v0.8b, v1.8b, v2.8b
+; CHECK-GI-NEXT: str d0, [x2]
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: .LBB13_2:
+; CHECK-GI-NEXT: mvn v0.8b, v0.8b
+; CHECK-GI-NEXT: ret
+entry:
+ %n = xor <8 x i8> %m, splat (i8 -1)
+ br i1 %c, label %if.then, label %if.else
+
+if.then:
+ %ns = xor i8 %s, -1
+ %ins = insertelement <8 x i8> poison, i8 %ns, i64 0
+ %spl = shufflevector <8 x i8> %ins, <8 x i8> poison, <8 x i32> zeroinitializer
+ %x = and <8 x i8> %m, %b
+ %y = and <8 x i8> %spl, %n
+ %r = or <8 x i8> %x, %y
+ store <8 x i8> %r, ptr %p
+ ret <8 x i8> %r
+
+if.else:
+ ret <8 x i8> %n
+}
diff --git a/llvm/test/Transforms/CodeGenPrepare/AArch64/sink-free-instructions.ll b/llvm/test/Transforms/CodeGenPrepare/AArch64/sink-free-instructions.ll
index 056237e70a540..132b093872973 100644
--- a/llvm/test/Transforms/CodeGenPrepare/AArch64/sink-free-instructions.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/AArch64/sink-free-instructions.ll
@@ -1124,4 +1124,40 @@ if.else:
ret <8 x i8> %b
}
+define <8 x i8> @no_sink_bsl_not_after_splat_not_multiuse(<8 x i8> %m, <8 x i8> %b, i8 %s, i1 %c, ptr %p) {
+; CHECK-LABEL: @no_sink_bsl_not_after_splat_not_multiuse(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[N:%.*]] = xor <8 x i8> [[M:%.*]], splat (i8 -1)
+; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: [[NS:%.*]] = xor i8 [[S:%.*]], -1
+; CHECK-NEXT: [[INS:%.*]] = insertelement <8 x i8> poison, i8 [[NS]], i64 0
+; CHECK-NEXT: [[SPL:%.*]] = shufflevector <8 x i8> [[INS]], <8 x i8> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP0:%.*]] = xor <8 x i8> [[M]], splat (i8 -1)
+; CHECK-NEXT: [[X:%.*]] = and <8 x i8> [[M]], [[B:%.*]]
+; CHECK-NEXT: [[Y:%.*]] = and <8 x i8> [[SPL]], [[TMP0]]
+; CHECK-NEXT: [[R:%.*]] = or <8 x i8> [[X]], [[Y]]
+; CHECK-NEXT: store <8 x i8> [[R]], ptr [[P:%.*]], align 8
+; CHECK-NEXT: ret <8 x i8> [[R]]
+; CHECK: if.else:
+; CHECK-NEXT: ret <8 x i8> [[N]]
+;
+entry:
+ %n = xor <8 x i8> %m, splat (i8 -1)
+ br i1 %c, label %if.then, label %if.else
+
+if.then:
+ %ns = xor i8 %s, -1
+ %ins = insertelement <8 x i8> poison, i8 %ns, i64 0
+ %spl = shufflevector <8 x i8> %ins, <8 x i8> poison, <8 x i32> zeroinitializer
+ %x = and <8 x i8> %m, %b
+ %y = and <8 x i8> %spl, %n
+ %r = or <8 x i8> %x, %y
+ store <8 x i8> %r, ptr %p
+ ret <8 x i8> %r
+
+if.else:
+ ret <8 x i8> %n
+}
+
!0 = !{i64 0, i64 128}
``````````
</details>
https://github.com/llvm/llvm-project/pull/232786
More information about the llvm-branch-commits
mailing list