llvm.org GIT mirror llvm / d90e506
R600/SI: Add pattern for bitcasting fp immediates to integers The backend now assumes that all immediates are integers. This allows us to simplify immediate handling code, becasue we no longer need to handle fp and integer immediates differently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225844 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 5 years ago
8 changed file(s) with 39 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
6767 switch (MO.getType()) {
6868 default:
6969 llvm_unreachable("unknown operand type");
70 case MachineOperand::MO_FPImmediate: {
71 const APFloat &FloatValue = MO.getFPImm()->getValueAPF();
72
73 if (&FloatValue.getSemantics() == &APFloat::IEEEsingle)
74 MCOp = MCOperand::CreateFPImm(FloatValue.convertToFloat());
75 else if (&FloatValue.getSemantics() == &APFloat::IEEEdouble)
76 MCOp = MCOperand::CreateFPImm(FloatValue.convertToDouble());
77 else
78 llvm_unreachable("Unhandled floating point type");
79
80 break;
81 }
8270 case MachineOperand::MO_Immediate:
8371 MCOp = MCOperand::CreateImm(MO.getImm());
8472 break;
172172 continue;
173173
174174 MachineOperand &OpToFold = MI.getOperand(1);
175 bool FoldingImm = OpToFold.isImm() || OpToFold.isFPImm();
175 bool FoldingImm = OpToFold.isImm();
176176
177177 // FIXME: We could also be folding things like FrameIndexes and
178178 // TargetIndexes.
209209
210210 if (FoldingImm) {
211211 const TargetRegisterClass *UseRC = MRI.getRegClass(UseOp.getReg());
212
213 if (OpToFold.isFPImm()) {
214 Imm = OpToFold.getFPImm()->getValueAPF().bitcastToAPInt();
215 } else {
216 Imm = APInt(64, OpToFold.getImm());
217 }
212 Imm = APInt(64, OpToFold.getImm());
218213
219214 // Split 64-bit constants into 32-bits for folding.
220215 if (UseOp.getSubReg()) {
10761076 const APFloat K1Val(BitsToFloat(0x2f800000));
10771077 const SDValue K1 = DAG.getConstantFP(K1Val, MVT::f32);
10781078
1079 const SDValue One = DAG.getTargetConstantFP(1.0, MVT::f32);
1079 const SDValue One = DAG.getConstantFP(1.0, MVT::f32);
10801080
10811081 EVT SetCCVT = getSetCCResultType(*DAG.getContext(), MVT::f32);
10821082
15481548 if (LHS.getOpcode() == ISD::FADD) {
15491549 SDValue A = LHS.getOperand(0);
15501550 if (A == LHS.getOperand(1)) {
1551 const SDValue Two = DAG.getTargetConstantFP(2.0, MVT::f32);
1551 const SDValue Two = DAG.getConstantFP(2.0, MVT::f32);
15521552 return DAG.getNode(AMDGPUISD::MAD, DL, VT, Two, A, RHS);
15531553 }
15541554 }
15571557 if (RHS.getOpcode() == ISD::FADD) {
15581558 SDValue A = RHS.getOperand(0);
15591559 if (A == RHS.getOperand(1)) {
1560 const SDValue Two = DAG.getTargetConstantFP(2.0, MVT::f32);
1560 const SDValue Two = DAG.getConstantFP(2.0, MVT::f32);
15611561 return DAG.getNode(AMDGPUISD::MAD, DL, VT, Two, A, LHS);
15621562 }
15631563 }
16011601
16021602 SDValue A = LHS.getOperand(0);
16031603 if (A == LHS.getOperand(1)) {
1604 const SDValue Two = DAG.getTargetConstantFP(2.0, MVT::f32);
1604 const SDValue Two = DAG.getConstantFP(2.0, MVT::f32);
16051605 SDValue NegRHS = DAG.getNode(ISD::FNEG, DL, VT, RHS);
16061606
16071607 return DAG.getNode(AMDGPUISD::MAD, DL, VT, Two, A, NegRHS);
16131613
16141614 SDValue A = RHS.getOperand(0);
16151615 if (A == RHS.getOperand(1)) {
1616 const SDValue NegTwo = DAG.getTargetConstantFP(-2.0, MVT::f32);
1616 const SDValue NegTwo = DAG.getConstantFP(-2.0, MVT::f32);
16171617 return DAG.getNode(AMDGPUISD::MAD, DL, VT, NegTwo, A, LHS);
16181618 }
16191619 }
735735 }
736736
737737 if (!Src1.isReg()) {
738 // Allow commuting instructions with Imm or FPImm operands.
739 if (NewMI || (!Src1.isImm() && !Src1.isFPImm()) ||
738 // Allow commuting instructions with Imm operands.
739 if (NewMI || !Src1.isImm() ||
740740 (!isVOP2(MI->getOpcode()) && !isVOP3(MI->getOpcode()))) {
741741 return nullptr;
742742 }
764764 unsigned SubReg = Src0.getSubReg();
765765 if (Src1.isImm())
766766 Src0.ChangeToImmediate(Src1.getImm());
767 else if (Src1.isFPImm())
768 Src0.ChangeToFPImmediate(Src1.getFPImm());
769767 else
770768 llvm_unreachable("Should only have immediates");
771769
980978 if (MO.isImm())
981979 return isInlineConstant(APInt(32, MO.getImm(), true));
982980
983 if (MO.isFPImm()) {
984 APFloat FpImm = MO.getFPImm()->getValueAPF();
985 return isInlineConstant(FpImm.bitcastToAPInt());
986 }
987
988981 return false;
989982 }
990983
991984 bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const {
992 return (MO.isImm() || MO.isFPImm()) && !isInlineConstant(MO);
985 return MO.isImm() && !isInlineConstant(MO);
993986 }
994987
995988 static bool compareMachineOp(const MachineOperand &Op0,
1002995 return Op0.getReg() == Op1.getReg();
1003996 case MachineOperand::MO_Immediate:
1004997 return Op0.getImm() == Op1.getImm();
1005 case MachineOperand::MO_FPImmediate:
1006 return Op0.getFPImm() == Op1.getFPImm();
1007998 default:
1008999 llvm_unreachable("Didn't expect to be comparing these operand types");
10091000 }
10131004 const MachineOperand &MO) const {
10141005 const MCOperandInfo &OpInfo = get(MI->getOpcode()).OpInfo[OpNo];
10151006
1016 assert(MO.isImm() || MO.isFPImm() || MO.isTargetIndex() || MO.isFI());
1007 assert(MO.isImm() || MO.isTargetIndex() || MO.isFI());
10171008
10181009 if (OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE)
10191010 return true;
11201111
11211112 // Make sure the register classes are correct
11221113 for (int i = 0, e = Desc.getNumOperands(); i != e; ++i) {
1114 if (MI->getOperand(i).isFPImm()) {
1115 ErrInfo = "FPImm Machine Operands are not supported. ISel should bitcast "
1116 "all fp values to integers.";
1117 return false;
1118 }
1119
11231120 switch (Desc.OpInfo[i].OperandType) {
11241121 case MCOI::OPERAND_REGISTER: {
1125 if ((MI->getOperand(i).isImm() || MI->getOperand(i).isFPImm()) &&
1122 if (MI->getOperand(i).isImm() &&
11261123 !isImmOperandLegal(MI, i, MI->getOperand(i))) {
11271124 ErrInfo = "Illegal immediate value for operand.";
11281125 return false;
11331130 // Check if this operand is an immediate.
11341131 // FrameIndex operands will be replaced by immediates, so they are
11351132 // allowed.
1136 if (!MI->getOperand(i).isImm() && !MI->getOperand(i).isFPImm() &&
1137 !MI->getOperand(i).isFI()) {
1133 if (!MI->getOperand(i).isImm() && !MI->getOperand(i).isFI()) {
11381134 ErrInfo = "Expected immediate, but got non-immediate";
11391135 return false;
11401136 }
11941190 // Verify SRC1 for VOP2 and VOPC
11951191 if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) {
11961192 const MachineOperand &Src1 = MI->getOperand(Src1Idx);
1197 if (Src1.isImm() || Src1.isFPImm()) {
1193 if (Src1.isImm()) {
11981194 ErrInfo = "VOP[2C] src1 cannot be an immediate.";
11991195 return false;
12001196 }
14781474
14791475
14801476 // Handle non-register types that are treated like immediates.
1481 assert(MO->isImm() || MO->isFPImm() || MO->isTargetIndex() || MO->isFI());
1477 assert(MO->isImm() || MO->isTargetIndex() || MO->isFI());
14821478
14831479 if (!DefinedRC) {
14841480 // This operand expects an immediate.
156156
157157 def as_i64imm: SDNodeXForm
158158 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i64);
159 }]>;
160
161 // Copied from the AArch64 backend:
162 def bitcast_fpimm_to_i32 : SDNodeXForm
163 return CurDAG->getTargetConstant(
164 N->getValueAPF().bitcastToAPInt().getZExtValue(), MVT::i32);
165 }]>;
166
167 // Copied from the AArch64 backend:
168 def bitcast_fpimm_to_i64 : SDNodeXForm
169 return CurDAG->getTargetConstant(
170 N->getValueAPF().bitcastToAPInt().getZExtValue(), MVT::i64);
159171 }]>;
160172
161173 def IMM8bit : PatLeaf <(imm),
25512551
25522552 def : Pat <
25532553 (SGPRImm<(f32 fpimm)>:$imm),
2554 (S_MOV_B32 fpimm:$imm)
2554 (S_MOV_B32 (f32 (bitcast_fpimm_to_i32 $imm)))
25552555 >;
25562556
25572557 def : Pat <
25612561
25622562 def : Pat <
25632563 (f32 fpimm:$imm),
2564 (V_MOV_B32_e32 fpimm:$imm)
2564 (V_MOV_B32_e32 (f32 (bitcast_fpimm_to_i32 $imm)))
25652565 >;
25662566
25672567 def : Pat <
25792579
25802580 def : Pat <
25812581 (f64 InlineFPImm:$imm),
2582 (S_MOV_B64 InlineFPImm:$imm)
2582 (S_MOV_B64 (f64 (bitcast_fpimm_to_i64 InlineFPImm:$imm)))
25832583 >;
25842584
25852585 /********** ===================== **********/
307307 #endif
308308
309309 // Clear this thread from the exec mask if the operand is negative
310 if ((Op.isImm() || Op.isFPImm())) {
310 if ((Op.isImm())) {
311311 // Constant operand: Set exec mask to 0 or do nothing
312 if (Op.isImm() ? (Op.getImm() & 0x80000000) :
313 Op.getFPImm()->isNegative()) {
312 if (Op.getImm() & 0x80000000) {
314313 BuildMI(MBB, &MI, DL, TII->get(AMDGPU::S_MOV_B64), AMDGPU::EXEC)
315314 .addImm(0);
316315 }
129129
130130 // Only one literal constant is allowed per instruction, so if src0 is a
131131 // literal constant then we can't do any folding.
132 if ((Src0->isImm() || Src0->isFPImm()) && TII->isLiteralConstant(*Src0))
132 if (Src0->isImm() && TII->isLiteralConstant(*Src0))
133133 return;
134134
135135
150150 if (MovSrc.isImm() && isUInt<32>(MovSrc.getImm())) {
151151 Src0->ChangeToImmediate(MovSrc.getImm());
152152 ConstantFolded = true;
153 } else if (MovSrc.isFPImm()) {
154 const ConstantFP *CFP = MovSrc.getFPImm();
155 if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) {
156 Src0->ChangeToFPImmediate(CFP);
157 ConstantFolded = true;
158 }
159153 }
160154 if (ConstantFolded) {
161155 if (MRI.use_empty(Reg))
192186 if (MI.getOpcode() == AMDGPU::S_MOV_B32) {
193187 const MachineOperand &Src = MI.getOperand(1);
194188
195 // TODO: Handle FPImm?
196189 if (Src.isImm()) {
197190 if (isInt<16>(Src.getImm()) && !TII->isInlineConstant(Src))
198191 MI.setDesc(TII->get(AMDGPU::S_MOVK_I32));