[llvm] [ARM] Avoid materializing constant 1 when generating cneg instructions (PR #146591)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 1 12:06:55 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: AZero13 (AZero13)
<details>
<summary>Changes</summary>
Port to ARM.
---
Full diff: https://github.com/llvm/llvm-project/pull/146591.diff
2 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+12)
- (modified) llvm/test/CodeGen/Thumb2/csel.ll (+13)
``````````diff
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 2f89e23993385..d9bea6c646ccf 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -5530,6 +5530,18 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
CC = ISD::getSetCCInverse(CC, LHS.getValueType());
}
+ ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
+ if (Opcode == ARMISD::CSNEG && RHSVal && RHSVal->isOne()) {
+ assert(CTVal && CFVal && "Expected constant operands for CSNEG.");
+ // Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to
+ // avoid materializing C.
+ if (CTVal == RHSVal && CC == ISD::SETEQ) {
+ Opcode = ARMISD::CSINV;
+ TrueVal = LHS;
+ FalseVal = DAG.getConstant(0, dl, FalseVal.getValueType());
+ }
+ }
+
if (Opcode) {
// If one of the constants is cheaper than another, materialise the
// cheaper one and let the csel generate the other.
diff --git a/llvm/test/CodeGen/Thumb2/csel.ll b/llvm/test/CodeGen/Thumb2/csel.ll
index d786bc076aff9..4a40c79edad41 100644
--- a/llvm/test/CodeGen/Thumb2/csel.ll
+++ b/llvm/test/CodeGen/Thumb2/csel.ll
@@ -379,3 +379,16 @@ entry:
%t = add i32 %s, %b
ret i32 %t
}
+
+; Rather than use a CNEG, use a CSINV to transform "a == 1 ? 1 : -1" toAdd commentMore actions
+; "a == 1 ? a : -1" to avoid materializing a constant.
+define i32 @test_cneg(i32 %x) {
+; CHECK-LABEL: test_cneg:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: cmp r0, #1
+; CHECK-NEXT: cinv r0, r0, ne
+; CHECK-NEXT: bx lr
+ %cmp = icmp eq i32 %x, 1
+ %res = select i1 %cmp, i32 1, i32 -1
+ ret i32 %res
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/146591
More information about the llvm-commits
mailing list