[llvm] [AArch64][GISel] Signed comparison using CMN is safe when the subtraction is nsw (PR #150480)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 24 10:45:24 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: AZero13 (AZero13)
<details>
<summary>Changes</summary>
https://github.com/llvm/llvm-project/pull/141993 but for GISel, though for LHS, we now do the inverse compare, something that SelDAG does not do as of now but I will do in a future patch.
---
Patch is 21.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/150480.diff
3 Files Affected:
- (modified) llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp (+3-1)
- (modified) llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp (+25-17)
- (modified) llvm/test/CodeGen/AArch64/cmp-to-cmn.ll (+316-121)
``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
index 0b798509c26da..1a1507512c899 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
@@ -50,8 +50,10 @@ bool AArch64GISelUtils::isCMN(const MachineInstr *MaybeSub,
//
// %sub = G_SUB 0, %y
// %cmp = G_ICMP eq/ne, %z, %sub
+ // or with signed comparisons with the no-signed-wrap flag set
if (!MaybeSub || MaybeSub->getOpcode() != TargetOpcode::G_SUB ||
- !CmpInst::isEquality(Pred))
+ (!CmpInst::isEquality(Pred) &&
+ !(CmpInst::isSigned(Pred) && MaybeSub->getFlag(MachineInstr::NoSWrap))))
return false;
auto MaybeZero =
getIConstantVRegValWithLookThrough(MaybeSub->getOperand(1).getReg(), MRI);
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 1381a9b70df87..61c1c84fbb4f0 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2506,12 +2506,12 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) {
return false;
}
auto &PredOp = Cmp->getOperand(1);
- auto Pred = static_cast<CmpInst::Predicate>(PredOp.getPredicate());
- const AArch64CC::CondCode InvCC =
- changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
MIB.setInstrAndDebugLoc(I);
emitIntegerCompare(/*LHS=*/Cmp->getOperand(2),
/*RHS=*/Cmp->getOperand(3), PredOp, MIB);
+ auto Pred = static_cast<CmpInst::Predicate>(PredOp.getPredicate());
+ const AArch64CC::CondCode InvCC =
+ changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
emitCSINC(/*Dst=*/AddDst, /*Src =*/AddLHS, /*Src2=*/AddLHS, InvCC, MIB);
I.eraseFromParent();
return true;
@@ -3574,10 +3574,10 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return false;
}
+ emitIntegerCompare(I.getOperand(2), I.getOperand(3), I.getOperand(1), MIB);
auto Pred = static_cast<CmpInst::Predicate>(I.getOperand(1).getPredicate());
const AArch64CC::CondCode InvCC =
changeICMPPredToAArch64CC(CmpInst::getInversePredicate(Pred));
- emitIntegerCompare(I.getOperand(2), I.getOperand(3), I.getOperand(1), MIB);
emitCSINC(/*Dst=*/I.getOperand(0).getReg(), /*Src1=*/AArch64::WZR,
/*Src2=*/AArch64::WZR, InvCC, MIB);
I.eraseFromParent();
@@ -5096,11 +5096,11 @@ bool AArch64InstructionSelector::tryOptSelect(GSelect &I) {
AArch64CC::CondCode CondCode;
if (CondOpc == TargetOpcode::G_ICMP) {
+ emitIntegerCompare(CondDef->getOperand(2), CondDef->getOperand(3),
+ CondDef->getOperand(1), MIB);
auto Pred =
static_cast<CmpInst::Predicate>(CondDef->getOperand(1).getPredicate());
CondCode = changeICMPPredToAArch64CC(Pred);
- emitIntegerCompare(CondDef->getOperand(2), CondDef->getOperand(3),
- CondDef->getOperand(1), MIB);
} else {
// Get the condition code for the select.
auto Pred =
@@ -5148,18 +5148,7 @@ MachineInstr *AArch64InstructionSelector::tryFoldIntegerCompare(
MachineInstr *LHSDef = getDefIgnoringCopies(LHS.getReg(), MRI);
MachineInstr *RHSDef = getDefIgnoringCopies(RHS.getReg(), MRI);
auto P = static_cast<CmpInst::Predicate>(Predicate.getPredicate());
- // Given this:
- //
- // x = G_SUB 0, y
- // G_ICMP x, z
- //
- // Produce this:
- //
- // cmn y, z
- if (isCMN(LHSDef, P, MRI))
- return emitCMN(LHSDef->getOperand(2), RHS, MIRBuilder);
- // Same idea here, but with the RHS of the compare instead:
//
// Given this:
//
@@ -5171,6 +5160,25 @@ MachineInstr *AArch64InstructionSelector::tryFoldIntegerCompare(
// cmn z, y
if (isCMN(RHSDef, P, MRI))
return emitCMN(LHS, RHSDef->getOperand(2), MIRBuilder);
+
+ // Same idea here, but with the LHS of the compare instead:
+ // Given this:
+ //
+ // x = G_SUB 0, y
+ // G_ICMP x, z
+ //
+ // Produce this:
+ //
+ // cmn y, z
+ // But be careful! We need to swap the predicate!
+ if (isCMN(LHSDef, P, MRI)) {
+ if (!CmpInst::isEquality(P)) {
+ P = CmpInst::getSwappedPredicate(P);
+ Predicate = MachineOperand::CreatePredicate(P);
+ }
+ return emitCMN(LHSDef->getOperand(2), RHS, MIRBuilder);
+ }
+
// Given this:
//
diff --git a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
index 5765e0acae269..a48e656dd2edd 100644
--- a/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
+++ b/llvm/test/CodeGen/AArch64/cmp-to-cmn.ll
@@ -1,14 +1,21 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,SDISEL
+; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s -global-isel | FileCheck %s --check-prefixes=CHECK,GISEL
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "arm64"
define i1 @test_EQ_IllEbT(i64 %a, i64 %b) {
-; CHECK-LABEL: test_EQ_IllEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn x0, x1
-; CHECK-NEXT: cset w0, eq
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_EQ_IllEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn x0, x1
+; SDISEL-NEXT: cset w0, eq
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_EQ_IllEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: cmn x1, x0
+; GISEL-NEXT: cset w0, eq
+; GISEL-NEXT: ret
entry:
%add = sub i64 0, %b
%cmp = icmp eq i64 %add, %a
@@ -16,11 +23,19 @@ entry:
}
define i1 @test_EQ_IliEbT(i64 %a, i32 %b) {
-; CHECK-LABEL: test_EQ_IliEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn x0, w1, sxtw
-; CHECK-NEXT: cset w0, eq
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_EQ_IliEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn x0, w1, sxtw
+; SDISEL-NEXT: cset w0, eq
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_EQ_IliEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: // kill: def $w1 killed $w1 def $x1
+; GISEL-NEXT: sxtw x8, w1
+; GISEL-NEXT: cmn x8, x0
+; GISEL-NEXT: cset w0, eq
+; GISEL-NEXT: ret
entry:
%conv = sext i32 %b to i64
%add = sub i64 0, %a
@@ -55,11 +70,19 @@ entry:
}
define i1 @test_EQ_IilEbT(i32 %a, i64 %b) {
-; CHECK-LABEL: test_EQ_IilEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn x1, w0, sxtw
-; CHECK-NEXT: cset w0, eq
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_EQ_IilEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn x1, w0, sxtw
+; SDISEL-NEXT: cset w0, eq
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_EQ_IilEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: // kill: def $w0 killed $w0 def $x0
+; GISEL-NEXT: sxtw x8, w0
+; GISEL-NEXT: cmn x8, x1
+; GISEL-NEXT: cset w0, eq
+; GISEL-NEXT: ret
entry:
%conv = sext i32 %a to i64
%add = sub i64 0, %b
@@ -68,11 +91,17 @@ entry:
}
define i1 @test_EQ_IiiEbT(i32 %a, i32 %b) {
-; CHECK-LABEL: test_EQ_IiiEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn w0, w1
-; CHECK-NEXT: cset w0, eq
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_EQ_IiiEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn w0, w1
+; SDISEL-NEXT: cset w0, eq
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_EQ_IiiEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: cmn w1, w0
+; GISEL-NEXT: cset w0, eq
+; GISEL-NEXT: ret
entry:
%add = sub i32 0, %b
%cmp = icmp eq i32 %add, %a
@@ -218,11 +247,17 @@ entry:
}
define i1 @test_NE_IllEbT(i64 %a, i64 %b) {
-; CHECK-LABEL: test_NE_IllEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn x0, x1
-; CHECK-NEXT: cset w0, ne
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_NE_IllEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn x0, x1
+; SDISEL-NEXT: cset w0, ne
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_NE_IllEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: cmn x1, x0
+; GISEL-NEXT: cset w0, ne
+; GISEL-NEXT: ret
entry:
%add = sub i64 0, %b
%cmp = icmp ne i64 %add, %a
@@ -230,11 +265,19 @@ entry:
}
define i1 @test_NE_IliEbT(i64 %a, i32 %b) {
-; CHECK-LABEL: test_NE_IliEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn x0, w1, sxtw
-; CHECK-NEXT: cset w0, ne
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_NE_IliEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn x0, w1, sxtw
+; SDISEL-NEXT: cset w0, ne
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_NE_IliEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: // kill: def $w1 killed $w1 def $x1
+; GISEL-NEXT: sxtw x8, w1
+; GISEL-NEXT: cmn x8, x0
+; GISEL-NEXT: cset w0, ne
+; GISEL-NEXT: ret
entry:
%conv = sext i32 %b to i64
%add = sub i64 0, %a
@@ -269,11 +312,19 @@ entry:
}
define i1 @test_NE_IilEbT(i32 %a, i64 %b) {
-; CHECK-LABEL: test_NE_IilEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn x1, w0, sxtw
-; CHECK-NEXT: cset w0, ne
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_NE_IilEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn x1, w0, sxtw
+; SDISEL-NEXT: cset w0, ne
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_NE_IilEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: // kill: def $w0 killed $w0 def $x0
+; GISEL-NEXT: sxtw x8, w0
+; GISEL-NEXT: cmn x8, x1
+; GISEL-NEXT: cset w0, ne
+; GISEL-NEXT: ret
entry:
%conv = sext i32 %a to i64
%add = sub i64 0, %b
@@ -282,11 +333,17 @@ entry:
}
define i1 @test_NE_IiiEbT(i32 %a, i32 %b) {
-; CHECK-LABEL: test_NE_IiiEbT:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: cmn w0, w1
-; CHECK-NEXT: cset w0, ne
-; CHECK-NEXT: ret
+; SDISEL-LABEL: test_NE_IiiEbT:
+; SDISEL: // %bb.0: // %entry
+; SDISEL-NEXT: cmn w0, w1
+; SDISEL-NEXT: cset w0, ne
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: test_NE_IiiEbT:
+; GISEL: // %bb.0: // %entry
+; GISEL-NEXT: cmn w1, w0
+; GISEL-NEXT: cset w0, ne
+; GISEL-NEXT: ret
entry:
%add = sub i32 0, %b
%cmp = icmp ne i32 %add, %a
@@ -444,161 +501,281 @@ define i1 @cmn_large_imm(i32 %a) {
}
define i1 @almost_immediate_neg_slt(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_slt:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, le
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_slt:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, le
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_slt:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #4097 // =0x1001
+; GISEL-NEXT: movk w8, #65281, lsl #16
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, lt
+; GISEL-NEXT: ret
%cmp = icmp slt i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_slt_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_slt_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, le
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_slt_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, le
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_slt_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-61439 // =0xffffffffffff1001
+; GISEL-NEXT: movk x8, #65281, lsl #16
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, lt
+; GISEL-NEXT: ret
%cmp = icmp slt i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_sge(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_sge:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, gt
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_sge:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, gt
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_sge:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #4097 // =0x1001
+; GISEL-NEXT: movk w8, #65281, lsl #16
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, ge
+; GISEL-NEXT: ret
%cmp = icmp sge i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_sge_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_sge_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, gt
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_sge_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, gt
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_sge_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-61439 // =0xffffffffffff1001
+; GISEL-NEXT: movk x8, #65281, lsl #16
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, ge
+; GISEL-NEXT: ret
%cmp = icmp sge i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_uge(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_uge:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, hi
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_uge:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, hi
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_uge:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #4097 // =0x1001
+; GISEL-NEXT: movk w8, #65281, lsl #16
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, hs
+; GISEL-NEXT: ret
%cmp = icmp uge i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_uge_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_uge_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, hi
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_uge_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, hi
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_uge_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-61439 // =0xffffffffffff1001
+; GISEL-NEXT: movk x8, #65281, lsl #16
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, hs
+; GISEL-NEXT: ret
%cmp = icmp uge i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_ult(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_ult:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, ls
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_ult:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, ls
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_ult:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #4097 // =0x1001
+; GISEL-NEXT: movk w8, #65281, lsl #16
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, lo
+; GISEL-NEXT: ret
%cmp = icmp ult i32 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_ult_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_ult_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4079, lsl #12 // =16707584
-; CHECK-NEXT: cset w0, ls
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_ult_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4079, lsl #12 // =16707584
+; SDISEL-NEXT: cset w0, ls
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_ult_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-61439 // =0xffffffffffff1001
+; GISEL-NEXT: movk x8, #65281, lsl #16
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, lo
+; GISEL-NEXT: ret
%cmp = icmp ult i64 %x, -16707583
ret i1 %cmp
}
define i1 @almost_immediate_neg_sle(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_sle:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, lt
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_sle:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, lt
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_sle:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #-16773121 // =0xff000fff
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, le
+; GISEL-NEXT: ret
%cmp = icmp sle i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_sle_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_sle_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, lt
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_sle_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, lt
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_sle_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, le
+; GISEL-NEXT: ret
%cmp = icmp sle i64 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_sgt(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_sgt:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, ge
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_sgt:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, ge
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_sgt:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #-16773121 // =0xff000fff
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, gt
+; GISEL-NEXT: ret
%cmp = icmp sgt i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_sgt_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_sgt_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, ge
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_sgt_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, ge
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_sgt_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, gt
+; GISEL-NEXT: ret
%cmp = icmp sgt i64 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ule(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_ule:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, lo
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_ule:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, lo
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_ule:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov w8, #-16773121 // =0xff000fff
+; GISEL-NEXT: cmp w0, w8
+; GISEL-NEXT: cset w0, ls
+; GISEL-NEXT: ret
%cmp = icmp ule i32 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ule_64(i64 %x) {
-; CHECK-LABEL: almost_immediate_neg_ule_64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn x0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, lo
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_ule_64:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn x0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, lo
+; SDISEL-NEXT: ret
+;
+; GISEL-LABEL: almost_immediate_neg_ule_64:
+; GISEL: // %bb.0:
+; GISEL-NEXT: mov x8, #-16773121 // =0xffffffffff000fff
+; GISEL-NEXT: cmp x0, x8
+; GISEL-NEXT: cset w0, ls
+; GISEL-NEXT: ret
%cmp = icmp ule i64 %x, -16773121
ret i1 %cmp
}
define i1 @almost_immediate_neg_ugt(i32 %x) {
-; CHECK-LABEL: almost_immediate_neg_ugt:
-; CHECK: // %bb.0:
-; CHECK-NEXT: cmn w0, #4095, lsl #12 // =16773120
-; CHECK-NEXT: cset w0, hs
-; CHECK-NEXT: ret
+; SDISEL-LABEL: almost_immediate_neg_ugt:
+; SDISEL: // %bb.0:
+; SDISEL-NEXT: cmn w0, #4095, lsl #12 // =16773120
+; SDISEL-NEXT: cset w0, hs
+; SDISEL-NE...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/150480
More information about the llvm-commits
mailing list