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