Skip to content

Commit bdd0093

Browse files
committed
[GlobalISel] Add G_IS_FPCLASS
Add a generic opcode to represent `llvm.is_fpclass` intrinsic. Differential Revision: https://reviews.llvm.org/D121454
1 parent 0252357 commit bdd0093

File tree

7 files changed

+103
-1
lines changed

7 files changed

+103
-1
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,16 @@ G_FCANONICALIZE
480480

481481
See :ref:`i_intr_llvm_canonicalize`.
482482

483+
G_IS_FPCLASS
484+
^^^^^^^^^^^^
485+
486+
Tests if the first operand, which must be floating-point scalar or vector, has
487+
floating-point class specified by the second operand. The third operand
488+
specifies floating-point semantics of the tested value. Returns non-zero (true)
489+
or zero (false). It's target specific whether a true value is 1, ~0U, or some
490+
other non-zero value. If the first operand is a vector, the returned value is a
491+
vector of the same length.
492+
483493
G_FMINNUM
484494
^^^^^^^^^
485495

llvm/include/llvm/ADT/APFloat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ struct APFloatBase {
155155
S_IEEEdouble,
156156
S_x87DoubleExtended,
157157
S_IEEEquad,
158-
S_PPCDoubleDouble
158+
S_PPCDoubleDouble,
159+
S_MaxSemantics = S_PPCDoubleDouble
159160
};
160161

161162
static const llvm::fltSemantics &EnumToSemantics(Semantics S);

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,9 @@ HANDLE_TARGET_OPCODE(G_FABS)
620620
/// f64) is allowed.
621621
HANDLE_TARGET_OPCODE(G_FCOPYSIGN)
622622

623+
/// Generic test for floating-point class.
624+
HANDLE_TARGET_OPCODE(G_IS_FPCLASS)
625+
623626
/// Generic FP canonicalize value.
624627
HANDLE_TARGET_OPCODE(G_FCANONICALIZE)
625628

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,13 @@ def G_FCANONICALIZE : GenericInstruction {
745745
let hasSideEffects = false;
746746
}
747747

748+
// Generic opcode equivalent to the llvm.is_fpclass intrinsic.
749+
def G_IS_FPCLASS: GenericInstruction {
750+
let OutOperandList = (outs type0:$dst);
751+
let InOperandList = (ins type1:$src, unknown:$test, unknown:$fpsem);
752+
let hasSideEffects = false;
753+
}
754+
748755
// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
749756
// values.
750757
//

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "llvm/ADT/StringRef.h"
3333
#include "llvm/ADT/Twine.h"
3434
#include "llvm/Analysis/EHPersonalities.h"
35+
#include "llvm/CodeGen/CodeGenCommonISel.h"
3536
#include "llvm/CodeGen/LiveInterval.h"
3637
#include "llvm/CodeGen/LiveIntervals.h"
3738
#include "llvm/CodeGen/LiveRangeCalc.h"
@@ -1650,6 +1651,43 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
16501651
verifyAllRegOpsScalar(*MI, *MRI);
16511652
break;
16521653
}
1654+
case TargetOpcode::G_IS_FPCLASS: {
1655+
LLT DestTy = MRI->getType(MI->getOperand(0).getReg());
1656+
LLT DestEltTy = DestTy.getScalarType();
1657+
if (!DestEltTy.isScalar()) {
1658+
report("Destination must be a scalar or vector of scalars", MI);
1659+
break;
1660+
}
1661+
LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1662+
LLT SrcEltTy = SrcTy.getScalarType();
1663+
if (!SrcEltTy.isScalar()) {
1664+
report("Source must be a scalar or vector of scalars", MI);
1665+
break;
1666+
}
1667+
if (!verifyVectorElementMatch(DestTy, SrcTy, MI))
1668+
break;
1669+
const MachineOperand &TestMO = MI->getOperand(2);
1670+
if (!TestMO.isImm()) {
1671+
report("floating-point class set (operand 2) must be an immediate", MI);
1672+
break;
1673+
}
1674+
int64_t Test = TestMO.getImm();
1675+
if (Test < 0 || Test > fcAllFlags) {
1676+
report("Incorrect floating-point class set (operand 2)", MI);
1677+
break;
1678+
}
1679+
const MachineOperand &SemanticsMO = MI->getOperand(3);
1680+
if (!SemanticsMO.isImm()) {
1681+
report("floating-point semantics (operand 3) must be an immediate", MI);
1682+
break;
1683+
}
1684+
int64_t Semantics = SemanticsMO.getImm();
1685+
if (Semantics < 0 || Semantics > APFloat::S_MaxSemantics) {
1686+
report("Incorrect floating-point semantics (operand 3)", MI);
1687+
break;
1688+
}
1689+
break;
1690+
}
16531691
default:
16541692
break;
16551693
}

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,9 @@
484484
# DEBUG-NEXT: G_FCOPYSIGN (opcode {{[0-9]+}}): 2 type indices
485485
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
486486
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
487+
# DEBUG-NEXT: G_IS_FPCLASS (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
488+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
489+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
487490
# DEBUG-NEXT: G_FCANONICALIZE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
488491
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
489492
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# RUN: not --crash llc -o - -march=aarch64 -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
2+
# REQUIRES: aarch64-registered-target
3+
4+
---
5+
name: test_fcmp
6+
legalized: true
7+
regBankSelected: false
8+
selected: false
9+
tracksRegLiveness: true
10+
liveins:
11+
body: |
12+
bb.0:
13+
liveins: $x0, $w0, $q0
14+
%s32:_(s32) = COPY $w0
15+
%ptr:_(p0) = COPY $x0
16+
%vector:_(<4 x s32>) = COPY $q0
17+
18+
%val1:_(s1) = G_IS_FPCLASS %s32, 1
19+
; CHECK: *** Bad machine code: Too few operands ***
20+
; CHECK: 4 operands expected, but 3 given.
21+
22+
%val2:_(p0) = G_IS_FPCLASS %s32, 3, 2
23+
; CHECK: *** Bad machine code: Destination must be a scalar or vector of scalars ***
24+
25+
%val3:_(s1) = G_IS_FPCLASS %s32, 1, 66
26+
; CHECK: *** Bad machine code: Incorrect floating-point semantics (operand 3) ***
27+
28+
%val4:_(s1) = G_IS_FPCLASS %s32, 7777, 2
29+
; CHECK: *** Bad machine code: Incorrect floating-point class set (operand 2) ***
30+
31+
%val5:_(s1) = G_IS_FPCLASS %ptr:_(p0), 3, 2
32+
; CHECK: *** Bad machine code: Source must be a scalar or vector of scalars ***
33+
34+
%var6:_(s1) = G_IS_FPCLASS %vector:_(<4 x s32>), 1, 2
35+
; CHECK: *** Bad machine code: operand types must be all-vector or all-scalar ***
36+
37+
%var7:_(<2 x s1>) = G_IS_FPCLASS %vector:_(<4 x s32>), 1, 2
38+
; CHECK: *** Bad machine code: operand types must preserve number of vector elements ***
39+
40+
...

0 commit comments

Comments
 (0)