[llvm] [ARM] Copy SMAX(lhs, 0) and SMIN(lhs, 0) patterns from AArch64 to ARM (PR #146565)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 1 09:21:15 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: AZero13 (AZero13)
<details>
<summary>Changes</summary>
They work on ARM too.
---
Full diff: https://github.com/llvm/llvm-project/pull/146565.diff
2 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+20)
- (added) llvm/test/CodeGen/ARM/min-max-combine.ll (+150)
``````````diff
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 2f89e23993385..c520bfa5d2468 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -5510,6 +5510,26 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue FalseVal = Op.getOperand(3);
ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FalseVal);
ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TrueVal);
+ ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS);
+ if (Op.getValueType().isInteger()) {
+ // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns.
+ // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1))
+ // (SELECT_CC setlt, lhs, 0, lhs, 0) -> (AND lhs, (SRA lhs, typesize-1))
+ // Both require less instructions than compare and conditional select.
+ if ((CC == ISD::SETGT || CC == ISD::SETLT) && LHS == TrueVal && RHSC &&
+ RHSC->isZero() && CFVal && CFVal->isZero() &&
+ LHS.getValueType() == RHS.getValueType()) {
+ EVT VT = LHS.getValueType();
+ SDValue Shift =
+ DAG.getNode(ISD::SRA, dl, VT, LHS,
+ DAG.getConstant(VT.getSizeInBits() - 1, dl, VT));
+
+ if (CC == ISD::SETGT)
+ Shift = DAG.getNOT(dl, Shift, VT);
+
+ return DAG.getNode(ISD::AND, dl, VT, LHS, Shift);
+ }
+ }
if (Subtarget->hasV8_1MMainlineOps() && CFVal && CTVal &&
LHS.getValueType() == MVT::i32 && RHS.getValueType() == MVT::i32) {
diff --git a/llvm/test/CodeGen/ARM/min-max-combine.ll b/llvm/test/CodeGen/ARM/min-max-combine.ll
new file mode 100644
index 0000000000000..b9a7690009337
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/min-max-combine.ll
@@ -0,0 +1,150 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=armv7a < %s | FileCheck %s --check-prefix=ARM
+; RUN: llc -mtriple=armv6m < %s | FileCheck %s --check-prefix=THUMB
+; RUN: llc -mtriple=armv7m < %s | FileCheck %s --check-prefix=THUMB2
+
+declare i8 @llvm.smax.i8(i8 %a, i8 %b) readnone
+
+define i8 @smaxi8_zero(i8 %a) {
+; ARM-LABEL: smaxi8_zero:
+; ARM: @ %bb.0:
+; ARM-NEXT: sxtb r0, r0
+; ARM-NEXT: bic r0, r0, r0, asr #31
+; ARM-NEXT: bx lr
+;
+; THUMB-LABEL: smaxi8_zero:
+; THUMB: @ %bb.0:
+; THUMB-NEXT: sxtb r0, r0
+; THUMB-NEXT: asrs r1, r0, #31
+; THUMB-NEXT: bics r0, r1
+; THUMB-NEXT: bx lr
+;
+; THUMB2-LABEL: smaxi8_zero:
+; THUMB2: @ %bb.0:
+; THUMB2-NEXT: sxtb r0, r0
+; THUMB2-NEXT: bic.w r0, r0, r0, asr #31
+; THUMB2-NEXT: bx lr
+ %c = call i8 @llvm.smax.i8(i8 %a, i8 0)
+ ret i8 %c
+}
+
+declare i16 @llvm.smax.i16(i16 %a, i16 %b) readnone
+
+define i16 @smaxi16_zero(i16 %a) {
+; ARM-LABEL: smaxi16_zero:
+; ARM: @ %bb.0:
+; ARM-NEXT: sxth r0, r0
+; ARM-NEXT: bic r0, r0, r0, asr #31
+; ARM-NEXT: bx lr
+;
+; THUMB-LABEL: smaxi16_zero:
+; THUMB: @ %bb.0:
+; THUMB-NEXT: sxth r0, r0
+; THUMB-NEXT: asrs r1, r0, #31
+; THUMB-NEXT: bics r0, r1
+; THUMB-NEXT: bx lr
+;
+; THUMB2-LABEL: smaxi16_zero:
+; THUMB2: @ %bb.0:
+; THUMB2-NEXT: sxth r0, r0
+; THUMB2-NEXT: bic.w r0, r0, r0, asr #31
+; THUMB2-NEXT: bx lr
+ %c = call i16 @llvm.smax.i16(i16 %a, i16 0)
+ ret i16 %c
+}
+
+declare i32 @llvm.smax.i32(i32 %a, i32 %b) readnone
+
+define i32 @smaxi32_zero(i32 %a) {
+; ARM-LABEL: smaxi32_zero:
+; ARM: @ %bb.0:
+; ARM-NEXT: bic r0, r0, r0, asr #31
+; ARM-NEXT: bx lr
+;
+; THUMB-LABEL: smaxi32_zero:
+; THUMB: @ %bb.0:
+; THUMB-NEXT: asrs r1, r0, #31
+; THUMB-NEXT: bics r0, r1
+; THUMB-NEXT: bx lr
+;
+; THUMB2-LABEL: smaxi32_zero:
+; THUMB2: @ %bb.0:
+; THUMB2-NEXT: bic.w r0, r0, r0, asr #31
+; THUMB2-NEXT: bx lr
+ %c = call i32 @llvm.smax.i32(i32 %a, i32 0)
+ ret i32 %c
+}
+
+; SMIN
+
+declare i8 @llvm.smin.i8(i8 %a, i8 %b) readnone
+
+define i8 @smini8_zero(i8 %a) {
+; ARM-LABEL: smini8_zero:
+; ARM: @ %bb.0:
+; ARM-NEXT: sxtb r0, r0
+; ARM-NEXT: and r0, r0, r0, asr #31
+; ARM-NEXT: bx lr
+;
+; THUMB-LABEL: smini8_zero:
+; THUMB: @ %bb.0:
+; THUMB-NEXT: sxtb r1, r0
+; THUMB-NEXT: asrs r0, r1, #31
+; THUMB-NEXT: ands r0, r1
+; THUMB-NEXT: bx lr
+;
+; THUMB2-LABEL: smini8_zero:
+; THUMB2: @ %bb.0:
+; THUMB2-NEXT: sxtb r0, r0
+; THUMB2-NEXT: and.w r0, r0, r0, asr #31
+; THUMB2-NEXT: bx lr
+ %c = call i8 @llvm.smin.i8(i8 %a, i8 0)
+ ret i8 %c
+}
+
+declare i16 @llvm.smin.i16(i16 %a, i16 %b) readnone
+
+define i16 @smini16_zero(i16 %a) {
+; ARM-LABEL: smini16_zero:
+; ARM: @ %bb.0:
+; ARM-NEXT: sxth r0, r0
+; ARM-NEXT: and r0, r0, r0, asr #31
+; ARM-NEXT: bx lr
+;
+; THUMB-LABEL: smini16_zero:
+; THUMB: @ %bb.0:
+; THUMB-NEXT: sxth r1, r0
+; THUMB-NEXT: asrs r0, r1, #31
+; THUMB-NEXT: ands r0, r1
+; THUMB-NEXT: bx lr
+;
+; THUMB2-LABEL: smini16_zero:
+; THUMB2: @ %bb.0:
+; THUMB2-NEXT: sxth r0, r0
+; THUMB2-NEXT: and.w r0, r0, r0, asr #31
+; THUMB2-NEXT: bx lr
+ %c = call i16 @llvm.smin.i16(i16 %a, i16 0)
+ ret i16 %c
+}
+
+declare i32 @llvm.smin.i32(i32 %a, i32 %b) readnone
+
+define i32 @smini32_zero(i32 %a) {
+; ARM-LABEL: smini32_zero:
+; ARM: @ %bb.0:
+; ARM-NEXT: and r0, r0, r0, asr #31
+; ARM-NEXT: bx lr
+;
+; THUMB-LABEL: smini32_zero:
+; THUMB: @ %bb.0:
+; THUMB-NEXT: asrs r1, r0, #31
+; THUMB-NEXT: ands r0, r1
+; THUMB-NEXT: bx lr
+;
+; THUMB2-LABEL: smini32_zero:
+; THUMB2: @ %bb.0:
+; THUMB2-NEXT: and.w r0, r0, r0, asr #31
+; THUMB2-NEXT: bx lr
+ %c = call i32 @llvm.smin.i32(i32 %a, i32 0)
+ ret i32 %c
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/146565
More information about the llvm-commits
mailing list