-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[AArch64][GISel] Signed comparison using CMN is safe when the subtraction is nsw #150480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-backend-aarch64 Author: AZero13 (AZero13) Changes#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:
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]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
9db10a3
to
56216f1
Compare
…tion is nsw llvm#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.
@davemgreen thoughts? |
#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.