Skip to content

Commit dc6de5d

Browse files
arsenmjrtc27
authored andcommitted
GlobalISel: Add G_FMAD instruction
llvm-svn: 371254
2 parents 84c9a18 + cf10372 commit dc6de5d

File tree

7 files changed

+29
-0
lines changed

7 files changed

+29
-0
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,13 @@ class MachineIRBuilder {
13721372
return buildInstr(TargetOpcode::G_FMA, {Dst}, {Src0, Src1, Src2});
13731373
}
13741374

1375+
/// Build and insert \p Res = G_FMAD \p Op0, \p Op1, \p Op2
1376+
MachineInstrBuilder buildFMAD(const DstOp &Dst, const SrcOp &Src0,
1377+
const SrcOp &Src1, const SrcOp &Src2,
1378+
Optional<unsigned> Flags = None) {
1379+
return buildInstr(TargetOpcode::G_FMAD, {Dst}, {Src0, Src1, Src2}, Flags);
1380+
}
1381+
13751382
/// Build and insert \p Res = G_FNEG \p Op0
13761383
MachineInstrBuilder buildFNeg(const DstOp &Dst, const SrcOp &Src0) {
13771384
return buildInstr(TargetOpcode::G_FNEG, {Dst}, {Src0});

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ HANDLE_TARGET_OPCODE(G_FMUL)
439439
/// Generic FMA multiplication. Behaves like llvm fma intrinsic
440440
HANDLE_TARGET_OPCODE(G_FMA)
441441

442+
/// Generic FP multiply and add. Behaves as separate fmul and fadd.
443+
HANDLE_TARGET_OPCODE(G_FMAD)
444+
442445
/// Generic FP division.
443446
HANDLE_TARGET_OPCODE(G_FDIV)
444447

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,15 @@ def G_FMA : GenericInstruction {
624624
let isCommutable = 0;
625625
}
626626

627+
/// Generic FP multiply and add. Perform a * b + c, while getting the
628+
/// same result as the separately rounded operations, unlike G_FMA.
629+
def G_FMAD : GenericInstruction {
630+
let OutOperandList = (outs type0:$dst);
631+
let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
632+
let hasSideEffects = 0;
633+
let isCommutable = 0;
634+
}
635+
627636
// Generic FP division.
628637
def G_FDIV : GenericInstruction {
629638
let OutOperandList = (outs type0:$dst);

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def : GINodeEquiv<G_UITOFP, uint_to_fp>;
7777
def : GINodeEquiv<G_FADD, fadd>;
7878
def : GINodeEquiv<G_FSUB, fsub>;
7979
def : GINodeEquiv<G_FMA, fma>;
80+
def : GINodeEquiv<G_FMAD, fmad>;
8081
def : GINodeEquiv<G_FMUL, fmul>;
8182
def : GINodeEquiv<G_FDIV, fdiv>;
8283
def : GINodeEquiv<G_FREM, frem>;

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,7 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
17531753
case TargetOpcode::G_FMUL:
17541754
case TargetOpcode::G_FSUB:
17551755
case TargetOpcode::G_FMA:
1756+
case TargetOpcode::G_FMAD:
17561757
case TargetOpcode::G_FNEG:
17571758
case TargetOpcode::G_FABS:
17581759
case TargetOpcode::G_FCANONICALIZE:
@@ -2828,6 +2829,7 @@ LegalizerHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
28282829
case G_FDIV:
28292830
case G_FREM:
28302831
case G_FMA:
2832+
case G_FMAD:
28312833
case G_FPOW:
28322834
case G_FEXP:
28332835
case G_FEXP2:

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@
312312
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
313313
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
314314
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
315+
# DEBUG-NEXT: G_FMAD (opcode 116): 1 type index, 0 imm indices
316+
# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined
317+
# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined
315318
# DEBUG-NEXT: G_FDIV (opcode {{[0-9]+}}): 1 type index, 0 imm indices
316319
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
317320
# DEBUG-NEXT: .. the first uncovered type index: 1, OK

llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ TEST_F(GISelMITest, TestBuildFPInsts) {
130130
B.buildFAdd(S64, Copies[0], Copies[1]);
131131
B.buildFSub(S64, Copies[0], Copies[1]);
132132
B.buildFMA(S64, Copies[0], Copies[1], Copies[2]);
133+
B.buildFMAD(S64, Copies[0], Copies[1], Copies[2]);
134+
B.buildFMAD(S64, Copies[0], Copies[1], Copies[2], MachineInstr::FmNoNans);
133135
B.buildFNeg(S64, Copies[0]);
134136
B.buildFAbs(S64, Copies[0]);
135137
B.buildFCopysign(S64, Copies[0], Copies[1]);
@@ -141,6 +143,8 @@ TEST_F(GISelMITest, TestBuildFPInsts) {
141143
; CHECK: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[COPY0]]:_, [[COPY1]]:_
142144
; CHECK: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[COPY0]]:_, [[COPY1]]:_
143145
; CHECK: [[FMA:%[0-9]+]]:_(s64) = G_FMA [[COPY0]]:_, [[COPY1]]:_, [[COPY2]]:_
146+
; CHECK: [[FMAD0:%[0-9]+]]:_(s64) = G_FMAD [[COPY0]]:_, [[COPY1]]:_, [[COPY2]]:_
147+
; CHECK: [[FMAD1:%[0-9]+]]:_(s64) = nnan G_FMAD [[COPY0]]:_, [[COPY1]]:_, [[COPY2]]:_
144148
; CHECK: [[FNEG:%[0-9]+]]:_(s64) = G_FNEG [[COPY0]]:_
145149
; CHECK: [[FABS:%[0-9]+]]:_(s64) = G_FABS [[COPY0]]:_
146150
; CHECK: [[FCOPYSIGN:%[0-9]+]]:_(s64) = G_FCOPYSIGN [[COPY0]]:_, [[COPY1]]:_

0 commit comments

Comments
 (0)