@@ -137,6 +137,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
137
137
setOperationAction (Op, MVT::f32, Expand);
138
138
}
139
139
140
+ if (Subtarget.hasStdExtF () && Subtarget.is64Bit ())
141
+ setOperationAction (ISD::BITCAST, MVT::i32, Custom);
142
+
140
143
if (Subtarget.hasStdExtD ()) {
141
144
setOperationAction (ISD::FMINNUM, MVT::f64, Legal);
142
145
setOperationAction (ISD::FMAXNUM, MVT::f64, Legal);
@@ -338,6 +341,17 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
338
341
return lowerFRAMEADDR (Op, DAG);
339
342
case ISD::RETURNADDR:
340
343
return lowerRETURNADDR (Op, DAG);
344
+ case ISD::BITCAST: {
345
+ assert (Subtarget.is64Bit () && Subtarget.hasStdExtF () &&
346
+ " Unexpected custom legalisation" );
347
+ SDLoc DL (Op);
348
+ SDValue Op0 = Op.getOperand (0 );
349
+ if (Op.getValueType () != MVT::f32 || Op0.getValueType () != MVT::i32)
350
+ return SDValue ();
351
+ SDValue NewOp0 = DAG.getNode (ISD::ANY_EXTEND, DL, MVT::i64, Op0);
352
+ SDValue FPConv = DAG.getNode (RISCVISD::FMV_W_X_RV64, DL, MVT::f32, NewOp0);
353
+ return FPConv;
354
+ }
341
355
}
342
356
}
343
357
@@ -579,6 +593,18 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
579
593
return ;
580
594
Results.push_back (customLegalizeToWOp (N, DAG));
581
595
break ;
596
+ case ISD::BITCAST: {
597
+ assert (N->getValueType (0 ) == MVT::i32 && Subtarget.is64Bit () &&
598
+ Subtarget.hasStdExtF () && " Unexpected custom legalisation" );
599
+ SDLoc DL (N);
600
+ SDValue Op0 = N->getOperand (0 );
601
+ if (Op0.getValueType () != MVT::f32)
602
+ return ;
603
+ SDValue FPConv =
604
+ DAG.getNode (RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64, Op0);
605
+ Results.push_back (DAG.getNode (ISD::TRUNCATE, DL, MVT::i32, FPConv));
606
+ break ;
607
+ }
582
608
}
583
609
}
584
610
@@ -633,6 +659,38 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
633
659
return SDValue ();
634
660
break ;
635
661
}
662
+ case RISCVISD::FMV_X_ANYEXTW_RV64: {
663
+ SDLoc DL (N);
664
+ SDValue Op0 = N->getOperand (0 );
665
+ // If the input to FMV_X_ANYEXTW_RV64 is just FMV_W_X_RV64 then the
666
+ // conversion is unnecessary and can be replaced with an ANY_EXTEND
667
+ // of the FMV_W_X_RV64 operand.
668
+ if (Op0->getOpcode () == RISCVISD::FMV_W_X_RV64) {
669
+ SDValue AExtOp =
670
+ DAG.getNode (ISD::ANY_EXTEND, DL, MVT::i64, Op0.getOperand (0 ));
671
+ return DCI.CombineTo (N, AExtOp);
672
+ }
673
+
674
+ // This is a target-specific version of a DAGCombine performed in
675
+ // DAGCombiner::visitBITCAST. It performs the equivalent of:
676
+ // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit)
677
+ // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit))
678
+ if (!(Op0.getOpcode () == ISD::FNEG || Op0.getOpcode () == ISD::FABS) ||
679
+ !Op0.getNode ()->hasOneUse ())
680
+ break ;
681
+ SDValue NewFMV = DAG.getNode (RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64,
682
+ Op0.getOperand (0 ));
683
+ APInt SignBit = APInt::getSignMask (32 ).sext (64 );
684
+ if (Op0.getOpcode () == ISD::FNEG) {
685
+ return DCI.CombineTo (N,
686
+ DAG.getNode (ISD::XOR, DL, MVT::i64, NewFMV,
687
+ DAG.getConstant (SignBit, DL, MVT::i64)));
688
+ }
689
+ assert (Op0.getOpcode () == ISD::FABS);
690
+ return DCI.CombineTo (N,
691
+ DAG.getNode (ISD::AND, DL, MVT::i64, NewFMV,
692
+ DAG.getConstant (~SignBit, DL, MVT::i64)));
693
+ }
636
694
}
637
695
638
696
return SDValue ();
@@ -874,7 +932,7 @@ static bool CC_RISCV(const DataLayout &DL, unsigned ValNo, MVT ValVT, MVT LocVT,
874
932
assert (XLen == 32 || XLen == 64 );
875
933
MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64;
876
934
if (ValVT == MVT::f32) {
877
- LocVT = MVT::i32 ;
935
+ LocVT = XLenVT ;
878
936
LocInfo = CCValAssign::BCvt;
879
937
}
880
938
@@ -1047,6 +1105,10 @@ static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
1047
1105
case CCValAssign::Full:
1048
1106
break ;
1049
1107
case CCValAssign::BCvt:
1108
+ if (VA.getLocVT () == MVT::i64 && VA.getValVT () == MVT::f32) {
1109
+ Val = DAG.getNode (RISCVISD::FMV_W_X_RV64, DL, MVT::f32, Val);
1110
+ break ;
1111
+ }
1050
1112
Val = DAG.getNode (ISD::BITCAST, DL, VA.getValVT (), Val);
1051
1113
break ;
1052
1114
}
@@ -1082,6 +1144,10 @@ static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val,
1082
1144
case CCValAssign::Full:
1083
1145
break ;
1084
1146
case CCValAssign::BCvt:
1147
+ if (VA.getLocVT () == MVT::i64 && VA.getValVT () == MVT::f32) {
1148
+ Val = DAG.getNode (RISCVISD::FMV_X_ANYEXTW_RV64, DL, MVT::i64, Val);
1149
+ break ;
1150
+ }
1085
1151
Val = DAG.getNode (ISD::BITCAST, DL, LocVT, Val);
1086
1152
break ;
1087
1153
}
@@ -1108,9 +1174,12 @@ static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
1108
1174
llvm_unreachable (" Unexpected CCValAssign::LocInfo" );
1109
1175
case CCValAssign::Full:
1110
1176
case CCValAssign::Indirect:
1177
+ case CCValAssign::BCvt:
1111
1178
ExtType = ISD::NON_EXTLOAD;
1112
1179
break ;
1113
1180
}
1181
+ if (ValVT == MVT::f32)
1182
+ LocVT = MVT::f32;
1114
1183
Val = DAG.getExtLoad (
1115
1184
ExtType, DL, LocVT, Chain, FIN,
1116
1185
MachinePointerInfo::getFixedStack (DAG.getMachineFunction (), FI), ValVT);
@@ -1759,6 +1828,10 @@ const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
1759
1828
return " RISCVISD::DIVUW" ;
1760
1829
case RISCVISD::REMUW:
1761
1830
return " RISCVISD::REMUW" ;
1831
+ case RISCVISD::FMV_W_X_RV64:
1832
+ return " RISCVISD::FMV_W_X_RV64" ;
1833
+ case RISCVISD::FMV_X_ANYEXTW_RV64:
1834
+ return " RISCVISD::FMV_X_ANYEXTW_RV64" ;
1762
1835
}
1763
1836
return nullptr ;
1764
1837
}
0 commit comments