llvm.org GIT mirror llvm / 8c89765
[ARM GlobalISel] Select G_FCONSTANT for VFP3 Make it possible to TableGen code for FCONSTS and FCONSTD. We need to make two changes to the TableGen descriptions of vfp_f32imm and vfp_f64imm respectively: * add GISelPredicateCode to check that the immediate fits in 8 bits; * extract the SDNodeXForms into separate definitions and create a GISDNodeXFormEquiv and a custom renderer function for each of them. There's a lot of boilerplate to get the actual value of the immediate, but it basically just boils down to calling ARM_AM::getFP32Imm or ARM_AM::getFP64Imm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358063 91177308-0d34-0410-b5e6-96231b3b80d8 Diana Picus 9 months ago
3 changed file(s) with 76 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
5151 let ParserMatchClass = FPImmOperand;
5252 }
5353
54 def vfp_f32imm_xform : SDNodeXForm
55 APFloat InVal = N->getValueAPF();
56 uint32_t enc = ARM_AM::getFP32Imm(InVal);
57 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
58 }]>;
59
60 def gi_vfp_f32imm : GICustomOperandRenderer<"renderVFPF32Imm">,
61 GISDNodeXFormEquiv;
62
5463 def vfp_f32imm : Operand,
5564 PatLeaf<(f32 fpimm), [{
5665 return ARM_AM::getFP32Imm(N->getValueAPF()) != -1;
57 }], SDNodeXForm
58 APFloat InVal = N->getValueAPF();
59 uint32_t enc = ARM_AM::getFP32Imm(InVal);
60 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
61 }]>> {
66 }], vfp_f32imm_xform> {
6267 let PrintMethod = "printFPImmOperand";
6368 let ParserMatchClass = FPImmOperand;
64 }
69 let GISelPredicateCode = [{
70 const auto &MO = MI.getOperand(1);
71 if (!MO.isFPImm())
72 return false;
73 return ARM_AM::getFP32Imm(MO.getFPImm()->getValueAPF()) != -1;
74 }];
75 }
76
77 def vfp_f64imm_xform : SDNodeXForm
78 APFloat InVal = N->getValueAPF();
79 uint32_t enc = ARM_AM::getFP64Imm(InVal);
80 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
81 }]>;
82
83 def gi_vfp_f64imm : GICustomOperandRenderer<"renderVFPF64Imm">,
84 GISDNodeXFormEquiv;
6585
6686 def vfp_f64imm : Operand,
6787 PatLeaf<(f64 fpimm), [{
6888 return ARM_AM::getFP64Imm(N->getValueAPF()) != -1;
69 }], SDNodeXForm
70 APFloat InVal = N->getValueAPF();
71 uint32_t enc = ARM_AM::getFP64Imm(InVal);
72 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
73 }]>> {
89 }], vfp_f64imm_xform> {
7490 let PrintMethod = "printFPImmOperand";
7591 let ParserMatchClass = FPImmOperand;
92 let GISelPredicateCode = [{
93 const auto &MO = MI.getOperand(1);
94 if (!MO.isFPImm())
95 return false;
96 return ARM_AM::getFP64Imm(MO.getFPImm()->getValueAPF()) != -1;
97 }];
7698 }
7799
78100 def alignedload16 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
135135 // if it doesn't know how to select a better one.
136136 unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank,
137137 unsigned Size) const;
138
139 void renderVFPF32Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
140 void renderVFPF64Imm(MachineInstrBuilder &New, const MachineInstr &Old) const;
138141
139142 #define GET_GLOBALISEL_PREDICATES_DECL
140143 #include "ARMGenGlobalISel.inc"
803806 return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
804807 }
805808
809 void ARMInstructionSelector::renderVFPF32Imm(
810 MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
811 assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
812 "Expected G_FCONSTANT");
813
814 APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
815 uint32_t FPImmEncoding = ARM_AM::getFP32Imm(FPImmValue);
816 assert(FPImmEncoding != -1 && "Invalid immediate value");
817
818 NewInstBuilder.addImm(FPImmEncoding);
819 }
820
821 void ARMInstructionSelector::renderVFPF64Imm(
822 MachineInstrBuilder &NewInstBuilder, const MachineInstr &OldInst) const {
823 assert(OldInst.getOpcode() == TargetOpcode::G_FCONSTANT &&
824 "Expected G_FCONSTANT");
825
826 APFloat FPImmValue = OldInst.getOperand(1).getFPImm()->getValueAPF();
827 uint64_t FPImmEncoding = ARM_AM::getFP64Imm(FPImmValue);
828 assert(FPImmEncoding != -1 && "Invalid immediate value");
829
830 NewInstBuilder.addImm(FPImmEncoding);
831 }
832
806833 bool ARMInstructionSelector::select(MachineInstr &I,
807834 CodeGenCoverage &CoverageInfo) const {
808835 assert(I.getParent() && "Instruction should be in a basic block!");
8080 registers:
8181 - { id: 0, class: gprb }
8282 - { id: 1, class: fprb }
83 # CHECK: constants:
84 # CHECK-NEXT: id: 0
85 # CHECK-NEXT: value: 'float -2.000000e+00'
86 # CHECK-NEXT: alignment: 4
87 # CHECK-NEXT: isTargetSpecific: false
83 # VFP3: constants: []
84 # VFP2: constants:
85 # VFP2-NEXT: id: 0
86 # VFP2-NEXT: value: 'float -2.000000e+00'
87 # VFP2-NEXT: alignment: 4
88 # VFP2-NEXT: isTargetSpecific: false
8889 body: |
8990 bb.0:
9091 liveins: $r0
9394 ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
9495
9596 %1(s32) = G_FCONSTANT float -2.0
96 ; CHECK: [[VREG:%[0-9]+]]:spr = VLDRS %const.0, 0, 14, $noreg :: (load 4 from constant-pool)
97 ; VFP3: [[VREG:%[0-9]+]]:spr = FCONSTS 128, 14, $noreg
98 ; VFP2: [[VREG:%[0-9]+]]:spr = VLDRS %const.0, 0, 14, $noreg :: (load 4 from constant-pool)
9799
98100 G_STORE %1(s32), %0 :: (store 4)
99101 ; CHECK: VSTRS [[VREG]], [[PTR]], 0, 14, $noreg
111113 registers:
112114 - { id: 0, class: gprb }
113115 - { id: 1, class: fprb }
114 # CHECK: constants:
115 # CHECK-NEXT: id: 0
116 # CHECK-NEXT: value: double 5.000000e-01
117 # CHECK-NEXT: alignment: 8
118 # CHECK-NEXT: isTargetSpecific: false
116 # VFP3: constants: []
117 # VFP2: constants:
118 # VFP2-NEXT: id: 0
119 # VFP2-NEXT: value: double 5.000000e-01
120 # VFP2-NEXT: alignment: 8
121 # VFP2-NEXT: isTargetSpecific: false
119122 body: |
120123 bb.0:
121124 liveins: $r0
124127 ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
125128
126129 %1(s64) = G_FCONSTANT double 5.0e-1
127 ; CHECK: [[VREG:%[0-9]+]]:dpr = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
130 ; VFP3: [[VREG:%[0-9]+]]:dpr = FCONSTD 96, 14, $noreg
131 ; VFP2: [[VREG:%[0-9]+]]:dpr = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
128132
129133 G_STORE %1(s64), %0 :: (store 8)
130134 ; CHECK: VSTRD [[VREG]], [[PTR]], 0, 14, $noreg