[llvm] [GlobalIsel] Add G_SCMP and G_UCMP instructions (PR #98894)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 15 05:59:03 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: Thorsten Schütt (tschuett)
<details>
<summary>Changes</summary>
https://github.com/llvm/llvm-project/pull/83227
---
Full diff: https://github.com/llvm/llvm-project/pull/98894.diff
11 Files Affected:
- (modified) llvm/docs/GlobalISel/GenericOpcode.rst (+20)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (+28)
- (modified) llvm/include/llvm/Support/TargetOpcodes.def (+6)
- (modified) llvm/include/llvm/Target/GenericOpcodes.td (+14)
- (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+12)
- (modified) llvm/lib/CodeGen/MachineVerifier.cpp (+20)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir (+6)
- (modified) llvm/test/MachineVerifier/test_g_extract_subvector.mir (+3-1)
- (modified) llvm/test/MachineVerifier/test_g_insert_subvector.mir (+2-1)
- (modified) llvm/test/MachineVerifier/test_g_vscale.mir (+2-1)
- (added) llvm/test/MachineVerifier/test_uscmp.mir (+19)
``````````diff
diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst
index b05394aeee003..4ef16ffc69bd8 100644
--- a/llvm/docs/GlobalISel/GenericOpcode.rst
+++ b/llvm/docs/GlobalISel/GenericOpcode.rst
@@ -348,6 +348,26 @@ G_ICMP
Perform integer comparison producing non-zero (true) or zero (false). It's
target specific whether a true value is 1, ~0U, or some other non-zero value.
+G_SCMP
+^^^^^^
+
+Perform signed 3-way integer comparison producing -1 (smaller), 0 (equal), or 1 (larger).
+
+.. code-block:: none
+
+ %5:_(s32) = G_SCMP %6, %2
+
+
+G_UCMP
+^^^^^^
+
+Perform unsigned 3-way integer comparison producing -1 (smaller), 0 (equal), or 1 (larger).
+
+.. code-block:: none
+
+ %7:_(s32) = G_UCMP %2, %6
+
+
G_SELECT
^^^^^^^^
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index e74136f34b234..56a77b8596a18 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -1273,6 +1273,34 @@ class MachineIRBuilder {
const SrcOp &Op0, const SrcOp &Op1,
std::optional<unsigned> Flags = std::nullopt);
+ /// Build and insert a \p Res = G_SCMP \p Op0, \p Op1
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+
+ /// \pre \p Res must be a generic virtual register with scalar or
+ /// vector type. Typically this starts as s2 or <N x s2>.
+ /// \pre \p Op0 and Op1 must be generic virtual registers with the
+ /// same number of elements as \p Res. If \p Res is a scalar,
+ /// \p Op0 must be a scalar.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildSCmp(const DstOp &Res, const SrcOp &Op0,
+ const SrcOp &Op1);
+
+ /// Build and insert a \p Res = G_UCMP \p Op0, \p Op1
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+
+ /// \pre \p Res must be a generic virtual register with scalar or
+ /// vector type. Typically this starts as s2 or <N x s2>.
+ /// \pre \p Op0 and Op1 must be generic virtual registers with the
+ /// same number of elements as \p Res. If \p Res is a scalar,
+ /// \p Op0 must be a scalar.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildUCmp(const DstOp &Res, const SrcOp &Op0,
+ const SrcOp &Op1);
+
/// Build and insert a \p Res = G_IS_FPCLASS \p Src, \p Mask
MachineInstrBuilder buildIsFPClass(const DstOp &Res, const SrcOp &Src,
unsigned Mask) {
diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def
index e7f40e87ed24a..ba3713cd68506 100644
--- a/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/llvm/include/llvm/Support/TargetOpcodes.def
@@ -503,6 +503,12 @@ HANDLE_TARGET_OPCODE(G_ICMP)
/// Generic floating-point comparison, also applicable to vectors.
HANDLE_TARGET_OPCODE(G_FCMP)
+/// Generic signed 3-way comparison.
+HANDLE_TARGET_OPCODE(G_SCMP)
+
+/// Generic unsigned 3-way comparison.
+HANDLE_TARGET_OPCODE(G_UCMP)
+
/// Generic select.
HANDLE_TARGET_OPCODE(G_SELECT)
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index e1710ff2d8abf..f26284e001dbd 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -430,6 +430,20 @@ def G_FCMP : GenericInstruction {
let hasSideEffects = false;
}
+// Generic signed three-way comparison.
+def G_SCMP : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src1, type1:$src2);
+ let hasSideEffects = false;
+}
+
+// Generic unsigned three-way comparison.
+def G_UCMP : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type1:$src1, type1:$src2);
+ let hasSideEffects = false;
+}
+
// Generic select
def G_SELECT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 06a6c1f93ef1f..7eb6cd4e0d798 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -911,6 +911,18 @@ MachineInstrBuilder MachineIRBuilder::buildFCmp(CmpInst::Predicate Pred,
return buildInstr(TargetOpcode::G_FCMP, Res, {Pred, Op0, Op1}, Flags);
}
+MachineInstrBuilder MachineIRBuilder::buildSCmp(const DstOp &Res,
+ const SrcOp &Op0,
+ const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_SCMP, Res, {Op0, Op1});
+}
+
+MachineInstrBuilder MachineIRBuilder::buildUCmp(const DstOp &Res,
+ const SrcOp &Op0,
+ const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_UCMP, Res, {Op0, Op1});
+}
+
MachineInstrBuilder
MachineIRBuilder::buildSelect(const DstOp &Res, const SrcOp &Tst,
const SrcOp &Op0, const SrcOp &Op1,
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 0a5b8bdbc9371..1a183d83d0891 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1544,6 +1544,26 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
break;
}
+ case TargetOpcode::G_SCMP:
+ case TargetOpcode::G_UCMP: {
+ LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
+ LLT SrcTy2 = MRI->getType(MI->getOperand(2).getReg());
+
+ if ((DstTy.isVector() != SrcTy.isVector()) ||
+ (DstTy.isVector() &&
+ DstTy.getElementCount() != SrcTy.getElementCount())) {
+ report("Generic vector scmp/ucmp must preserve number of lanes", MI);
+ break;
+ }
+
+ if (SrcTy != SrcTy2) {
+ report("Generic scmp/ucmp must have same input types", MI);
+ break;
+ }
+
+ break;
+ }
case TargetOpcode::G_EXTRACT: {
const MachineOperand &SrcOp = MI->getOperand(1);
if (!SrcOp.isReg()) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
index 1f048528ea153..26687c915ecb2 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
@@ -351,6 +351,12 @@
# DEBUG-NEXT: G_FCMP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
+# DEBUG-NEXT: G_SCMP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: G_UCMP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
+# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
+# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: G_SELECT (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
diff --git a/llvm/test/MachineVerifier/test_g_extract_subvector.mir b/llvm/test/MachineVerifier/test_g_extract_subvector.mir
index bc167d2eb7bcd..fe04471563e49 100644
--- a/llvm/test/MachineVerifier/test_g_extract_subvector.mir
+++ b/llvm/test/MachineVerifier/test_g_extract_subvector.mir
@@ -1,4 +1,6 @@
-# RUN: not --crash llc -o - -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
+# RUN: not --crash llc -o - -run-pass=none -mtriple=arm64 -verify-machineinstrs %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
---
name: g_extract_subvector
tracksRegLiveness: true
diff --git a/llvm/test/MachineVerifier/test_g_insert_subvector.mir b/llvm/test/MachineVerifier/test_g_insert_subvector.mir
index dce30cdb6b1e5..25cb4ca3c4529 100644
--- a/llvm/test/MachineVerifier/test_g_insert_subvector.mir
+++ b/llvm/test/MachineVerifier/test_g_insert_subvector.mir
@@ -1,4 +1,5 @@
-# RUN: not --crash llc -o - -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
+# RUN: not --crash llc -o - -run-pass=none -mtriple=arm64 -verify-machineinstrs %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
---
name: g_splat_vector
diff --git a/llvm/test/MachineVerifier/test_g_vscale.mir b/llvm/test/MachineVerifier/test_g_vscale.mir
index 78854620913a1..f4ff76766a84e 100644
--- a/llvm/test/MachineVerifier/test_g_vscale.mir
+++ b/llvm/test/MachineVerifier/test_g_vscale.mir
@@ -1,4 +1,5 @@
-# RUN: not --crash llc -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not --crash llc -verify-machineinstrs -mtriple=arm64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
---
name: g_vscale
diff --git a/llvm/test/MachineVerifier/test_uscmp.mir b/llvm/test/MachineVerifier/test_uscmp.mir
new file mode 100644
index 0000000000000..0716399c865d5
--- /dev/null
+++ b/llvm/test/MachineVerifier/test_uscmp.mir
@@ -0,0 +1,19 @@
+# RUN: not --crash llc -verify-machineinstrs -mtriple=arm64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
+---
+name: test_uscmp
+body: |
+ bb.0:
+
+ %3:_(<2 x s32>) = G_IMPLICIT_DEF
+ %4:_(<2 x s32>) = G_IMPLICIT_DEF
+ ; CHECK: Generic vector scmp/ucmp must preserve number of lanes
+ %5:_(s1) = G_UCMP %3, %4
+
+ %12:_(s32) = G_CONSTANT i32 0
+ %13:_(s64) = G_CONSTANT i64 2
+ ; CHECK: Generic scmp/ucmp must have same input types
+ %14:_(s1) = G_SCMP %12, %13
+
+...
``````````
</details>
https://github.com/llvm/llvm-project/pull/98894
More information about the llvm-commits
mailing list