llvm.org GIT mirror llvm / e14caa7
GlobalISel: Use the original flags when lowering fneg to fsub This was ignoring the flag on fneg, and using the source instruction's flags. Also fixes tests missing from r358702. Note the expansion itself isn't correct without nnan, but that should be fixed separately. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363637 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault a month ago
4 changed file(s) with 108 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
14621462 auto Zero = MIRBuilder.buildFConstant(Ty, ZeroForNegation);
14631463 unsigned SubByReg = MI.getOperand(1).getReg();
14641464 unsigned ZeroReg = Zero->getOperand(0).getReg();
1465 MachineInstr *SrcMI = MRI.getVRegDef(SubByReg);
14661465 MIRBuilder.buildInstr(TargetOpcode::G_FSUB, {Res}, {ZeroReg, SubByReg},
1467 SrcMI->getFlags());
1466 MI.getFlags());
14681467 MI.eraseFromParent();
14691468 return Legalized;
14701469 }
0 ; RUN: llc -march=amdgcn -mcpu=fiji -O0 -stop-after=irtranslator -global-isel %s -o - | FileCheck %s
1
2 ; Check flags are preserved for a regular instruction.
3 ; CHECK-LABEL: name: fadd_nnan
4 ; CHECK: nnan G_FADD
5 define amdgpu_kernel void @fadd_nnan(float %arg0, float %arg1) {
6 %res = fadd nnan float %arg0, %arg1
7 store float %res, float addrspace(1)* undef
8 ret void
9 }
10
11 ; Check flags are preserved for a specially handled intrinsic
12 ; CHECK-LABEL: name: fma_fast
13 ; CHECK: nnan ninf nsz arcp contract afn reassoc G_FMA
14 define amdgpu_kernel void @fma_fast(float %arg0, float %arg1, float %arg2) {
15 %res = call fast float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
16 store float %res, float addrspace(1)* undef
17 ret void
18 }
19
20 ; Check flags are preserved for an arbitrarry target intrinsic
21 ; CHECK-LABEL: name: rcp_nsz
22 ; CHECK: = nsz G_INTRINSIC intrinsic(@llvm.amdgcn.rcp), %8(s32)
23 define amdgpu_kernel void @rcp_nsz(float %arg0) {
24 %res = call nsz float @llvm.amdgcn.rcp.f32 (float %arg0)
25 store float %res, float addrspace(1)* undef
26 ret void
27 }
28
29 declare float @llvm.fma.f32(float, float, float)
30 declare float @llvm.amdgcn.rcp.f32(float)
5555 %0:_(s64) = COPY $vgpr0_vgpr1
5656 %1:_(s64) = COPY $vgpr2_vgpr3
5757 %2:_(s64) = G_FSUB %0, %1
58 $vgpr0_vgpr1 = COPY %2
59 ...
60
61 ---
62 name: test_fsub_s64_fmf
63 body: |
64 bb.0:
65 liveins: $vgpr0_vgpr1, $vgpr2_vgpr3
66
67 ; SI-LABEL: name: test_fsub_s64_fmf
68 ; SI: [[COPY:%[0-9]+]]:_(s64) = COPY $vgpr0_vgpr1
69 ; SI: [[COPY1:%[0-9]+]]:_(s64) = COPY $vgpr2_vgpr3
70 ; SI: [[FNEG:%[0-9]+]]:_(s64) = G_FNEG [[COPY1]]
71 ; SI: %2:_(s64) = nnan nsz G_FADD [[COPY]], [[FNEG]]
72 ; SI: $vgpr0_vgpr1 = COPY %2(s64)
73 ; VI-LABEL: name: test_fsub_s64_fmf
74 ; VI: [[COPY:%[0-9]+]]:_(s64) = COPY $vgpr0_vgpr1
75 ; VI: [[COPY1:%[0-9]+]]:_(s64) = COPY $vgpr2_vgpr3
76 ; VI: [[FNEG:%[0-9]+]]:_(s64) = G_FNEG [[COPY1]]
77 ; VI: %2:_(s64) = nnan nsz G_FADD [[COPY]], [[FNEG]]
78 ; VI: $vgpr0_vgpr1 = COPY %2(s64)
79 ; GFX9-LABEL: name: test_fsub_s64_fmf
80 ; GFX9: [[COPY:%[0-9]+]]:_(s64) = COPY $vgpr0_vgpr1
81 ; GFX9: [[COPY1:%[0-9]+]]:_(s64) = COPY $vgpr2_vgpr3
82 ; GFX9: [[FNEG:%[0-9]+]]:_(s64) = G_FNEG [[COPY1]]
83 ; GFX9: %2:_(s64) = nnan nsz G_FADD [[COPY]], [[FNEG]]
84 ; GFX9: $vgpr0_vgpr1 = COPY %2(s64)
85 %0:_(s64) = COPY $vgpr0_vgpr1
86 %1:_(s64) = COPY $vgpr2_vgpr3
87 %2:_(s64) = nnan nsz G_FSUB %0, %1
5888 $vgpr0_vgpr1 = COPY %2
5989 ...
6090
728728
729729 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
730730 }
731
732 // FNEG expansion in terms of FSUB
733 TEST_F(GISelMITest, LowerFNEG) {
734 if (!TM)
735 return;
736
737 // Declare your legalization info
738 DefineLegalizerInfo(A, {
739 getActionDefinitionsBuilder(G_FSUB).legalFor({s64});
740 });
741
742 // Build Instr. Make sure FMF are preserved.
743 auto FAdd =
744 B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},
745 MachineInstr::MIFlag::FmNsz);
746
747 // Should not propagate the flags of src instruction.
748 auto FNeg0 =
749 B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},
750 {MachineInstr::MIFlag::FmArcp});
751
752 // Preserve the one flag.
753 auto FNeg1 =
754 B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},
755 MachineInstr::MIFlag::FmNoInfs);
756
757 AInfo Info(MF->getSubtarget());
758 DummyGISelObserver Observer;
759 LegalizerHelper Helper(*MF, Info, Observer, B);
760 // Perform Legalization
761 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
762 Helper.lower(*FNeg0, 0, LLT::scalar(64)));
763 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
764 Helper.lower(*FNeg1, 0, LLT::scalar(64)));
765
766 auto CheckStr = R"(
767 CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_
768 CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_FCONSTANT double -0.000000e+00
769 CHECK: [[FSUB0:%[0-9]+]]:_(s64) = arcp G_FSUB [[CONST0]]:_, [[FADD]]:_
770 CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_FCONSTANT double -0.000000e+00
771 CHECK: [[FSUB1:%[0-9]+]]:_(s64) = ninf G_FSUB [[CONST1]]:_, %0:_
772 )";
773
774 // Check
775 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
776 }
731777 } // namespace