@@ -294,6 +294,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
294
294
// the atomic operations in order to exploit SystemZ instructions.
295
295
setOperationAction (ISD::ATOMIC_LOAD, MVT::i128 , Custom);
296
296
setOperationAction (ISD::ATOMIC_STORE, MVT::i128 , Custom);
297
+ setOperationAction (ISD::ATOMIC_LOAD, MVT::f128 , Custom);
297
298
298
299
// Mark sign/zero extending atomic loads as legal, which will make
299
300
// DAGCombiner fold extensions into atomic loads if possible.
@@ -935,9 +936,6 @@ bool SystemZTargetLowering::hasInlineStackProbe(const MachineFunction &MF) const
935
936
936
937
TargetLowering::AtomicExpansionKind
937
938
SystemZTargetLowering::shouldCastAtomicLoadInIR (LoadInst *LI) const {
938
- // Lower fp128 the same way as i128.
939
- if (LI->getType ()->isFP128Ty ())
940
- return AtomicExpansionKind::CastToInteger;
941
939
return AtomicExpansionKind::None;
942
940
}
943
941
@@ -4550,7 +4548,9 @@ SDValue SystemZTargetLowering::lowerATOMIC_FENCE(SDValue Op,
4550
4548
SDValue SystemZTargetLowering::lowerATOMIC_LDST_I128 (SDValue Op,
4551
4549
SelectionDAG &DAG) const {
4552
4550
auto *Node = cast<AtomicSDNode>(Op.getNode ());
4553
- assert (Node->getMemoryVT () == MVT::i128 && " Only custom lowering i128." );
4551
+ assert (
4552
+ (Node->getMemoryVT () == MVT::i128 || Node->getMemoryVT () == MVT::f128 ) &&
4553
+ " Only custom lowering i128 or f128." );
4554
4554
// Use same code to handle both legal and non-legal i128 types.
4555
4555
SmallVector<SDValue, 2 > Results;
4556
4556
LowerOperationWrapper (Node, Results, DAG);
@@ -6249,6 +6249,41 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
6249
6249
}
6250
6250
}
6251
6251
6252
+ // Manually lower a bitcast to avoid introducing illegal types after type
6253
+ // legalization.
6254
+ static SDValue expandBitCastI128ToF128 (SelectionDAG &DAG, SDValue Src,
6255
+ SDValue Chain, const SDLoc &SL) {
6256
+ MachineFunction &MF = DAG.getMachineFunction ();
6257
+ const DataLayout &DL = DAG.getDataLayout ();
6258
+
6259
+ assert (DL.isBigEndian ());
6260
+
6261
+ Align F128Align = DL.getPrefTypeAlign (Type::getFP128Ty (*DAG.getContext ()));
6262
+ SDValue StackTemp = DAG.CreateStackTemporary (MVT::f128 , F128Align.value ());
6263
+ int FI = cast<FrameIndexSDNode>(StackTemp)->getIndex ();
6264
+ Align A = MF.getFrameInfo ().getObjectAlign (FI);
6265
+
6266
+ SDValue Hi =
6267
+ DAG.getTargetExtractSubreg (SystemZ::subreg_h64, SL, MVT::i64 , Src);
6268
+ SDValue Lo =
6269
+ DAG.getTargetExtractSubreg (SystemZ::subreg_l64, SL, MVT::i64 , Src);
6270
+
6271
+ TypeSize Offset = MVT (MVT::i64 ).getStoreSize ();
6272
+ SDValue StackTempOffset = DAG.getObjectPtrOffset (SL, StackTemp, Offset);
6273
+
6274
+ MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack (MF, FI);
6275
+
6276
+ SDValue StoreHi = DAG.getStore (Chain, SL, Lo, StackTempOffset, PtrInfo, A);
6277
+ SDValue StoreLo =
6278
+ DAG.getStore (Chain, SL, Hi, StackTemp, PtrInfo.getWithOffset (Offset),
6279
+ commonAlignment (A, Offset));
6280
+
6281
+ SDValue StoreChain =
6282
+ DAG.getNode (ISD::TokenFactor, SL, MVT::Other, {StoreLo, StoreHi});
6283
+
6284
+ return DAG.getLoad (MVT::f128 , SL, StoreChain, StackTemp, PtrInfo, A);
6285
+ }
6286
+
6252
6287
// Lower operations with invalid operand or result types (currently used
6253
6288
// only for 128-bit integer types).
6254
6289
void
@@ -6263,8 +6298,25 @@ SystemZTargetLowering::LowerOperationWrapper(SDNode *N,
6263
6298
MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand ();
6264
6299
SDValue Res = DAG.getMemIntrinsicNode (SystemZISD::ATOMIC_LOAD_128,
6265
6300
DL, Tys, Ops, MVT::i128 , MMO);
6266
- Results.push_back (lowerGR128ToI128 (DAG, Res));
6267
- Results.push_back (Res.getValue (1 ));
6301
+
6302
+ EVT VT = N->getValueType (0 );
6303
+
6304
+ if (VT == MVT::i128 || isTypeLegal (MVT::i128 )) {
6305
+ SDValue Lowered = lowerGR128ToI128 (DAG, Res);
6306
+ Results.push_back (DAG.getBitcast (VT, Lowered));
6307
+ Results.push_back (Res.getValue (1 ));
6308
+ } else {
6309
+ // For the f128 case, after type legalization, we cannot produce a bitcast
6310
+ // with an illegal type (i.e. i128), so introduce a stack store and reload
6311
+ //
6312
+ // FIXME: Really v2i64 should be legal, and should be used in place of
6313
+ // unttyped. Then we could emit the bitcast which will potentially avoid
6314
+ // the stack usage after combining.
6315
+ SDValue Cast = expandBitCastI128ToF128 (DAG, Res, Res.getValue (1 ), DL);
6316
+ Results.push_back (Cast);
6317
+ Results.push_back (Cast.getValue (1 ));
6318
+ }
6319
+
6268
6320
break ;
6269
6321
}
6270
6322
case ISD::ATOMIC_STORE: {
0 commit comments