aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorAtariDreams <gfunni234@gmail.com>2024-06-21 10:48:04 -0400
committerGitHub <noreply@github.com>2024-06-21 15:48:04 +0100
commit4e6835d4d980b0a1ea6a9de1c2e8360fd0810bba (patch)
tree231645c800c14ba507e5e93c862d3dce16677922 /llvm/lib/Target
parenta9efcbf490d9b8f46ec37062ca8653b4068000e5 (diff)
downloadllvm-4e6835d4d980b0a1ea6a9de1c2e8360fd0810bba.zip
llvm-4e6835d4d980b0a1ea6a9de1c2e8360fd0810bba.tar.gz
llvm-4e6835d4d980b0a1ea6a9de1c2e8360fd0810bba.tar.bz2
[AArch64] Use ccmn to compare negative immediates between -1 and -31 (#95825)
Because ccmn is like a + b, it works when using cmp but with values that when negated are in the range of 1 through 31
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp6
-rw-r--r--llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp9
2 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 7f82171..0c834ac 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3519,6 +3519,12 @@ static SDValue emitConditionalComparison(SDValue LHS, SDValue RHS,
RHS = DAG.getNode(ISD::FP_EXTEND, DL, MVT::f32, RHS);
}
Opcode = AArch64ISD::FCCMP;
+ } else if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(RHS)) {
+ APInt Imm = Const->getAPIntValue();
+ if (Imm.isNegative() && Imm.sgt(-32)) {
+ Opcode = AArch64ISD::CCMN;
+ RHS = DAG.getConstant(Imm.abs(), DL, Const->getValueType(0));
+ }
} else if (RHS.getOpcode() == ISD::SUB) {
SDValue SubOp0 = RHS.getOperand(0);
if (isNullConstant(SubOp0) && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index d32007e..0357a72 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -4667,7 +4667,6 @@ MachineInstr *AArch64InstructionSelector::emitConditionalComparison(
Register LHS, Register RHS, CmpInst::Predicate CC,
AArch64CC::CondCode Predicate, AArch64CC::CondCode OutCC,
MachineIRBuilder &MIB) const {
- // TODO: emit CMN as an optimization.
auto &MRI = *MIB.getMRI();
LLT OpTy = MRI.getType(LHS);
unsigned CCmpOpc;
@@ -4675,10 +4674,12 @@ MachineInstr *AArch64InstructionSelector::emitConditionalComparison(
if (CmpInst::isIntPredicate(CC)) {
assert(OpTy.getSizeInBits() == 32 || OpTy.getSizeInBits() == 64);
C = getIConstantVRegValWithLookThrough(RHS, MRI);
- if (C && C->Value.ult(32))
+ if (!C || C->Value.sgt(31) || C->Value.slt(-31))
+ CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMPWr : AArch64::CCMPXr;
+ else if (C->Value.ule(31))
CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMPWi : AArch64::CCMPXi;
else
- CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMPWr : AArch64::CCMPXr;
+ CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMNWi : AArch64::CCMNXi;
} else {
assert(OpTy.getSizeInBits() == 16 || OpTy.getSizeInBits() == 32 ||
OpTy.getSizeInBits() == 64);
@@ -4703,6 +4704,8 @@ MachineInstr *AArch64InstructionSelector::emitConditionalComparison(
MIB.buildInstr(CCmpOpc, {}, {LHS});
if (CCmpOpc == AArch64::CCMPWi || CCmpOpc == AArch64::CCMPXi)
CCmp.addImm(C->Value.getZExtValue());
+ else if (CCmpOpc == AArch64::CCMNWi || CCmpOpc == AArch64::CCMNXi)
+ CCmp.addImm(C->Value.abs().getZExtValue());
else
CCmp.addReg(RHS);
CCmp.addImm(NZCV).addImm(Predicate);