@@ -10370,14 +10370,66 @@ TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
10370
10370
assert (LoadedVT.isInteger () && !LoadedVT.isVector () &&
10371
10371
" Unaligned load of unsupported type." );
10372
10372
10373
+ Align BaseAlignment = LD->getBaseAlign ();
10374
+ Align Alignment = LD->getAlign ();
10375
+
10376
+ // Divide the load according to the latest align information
10377
+ if (commonAlignment (BaseAlignment,
10378
+ Alignment.value () + LD->getPointerInfo ().Offset ) >
10379
+ Alignment) {
10380
+ ISD::LoadExtType HiExtType = LD->getExtensionType ();
10381
+
10382
+ // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD.
10383
+ if (HiExtType == ISD::NON_EXTLOAD)
10384
+ HiExtType = ISD::ZEXTLOAD;
10385
+
10386
+ bool IsLE = DAG.getDataLayout ().isLittleEndian ();
10387
+ unsigned NumBytes = LoadedVT.getSizeInBits () / 8 ;
10388
+ // LE/BE use the same initial Alignment
10389
+ unsigned PtrOffset = IsLE ? 0 : (NumBytes - Alignment.value ());
10390
+ unsigned RemainderBytes = NumBytes;
10391
+ SDValue Result = DAG.getConstant (0 , dl, VT);
10392
+ SmallVector<SDValue, 4 > Chains;
10393
+ while (RemainderBytes) {
10394
+ unsigned CurrBytes =
10395
+ std::min (1ul << Log2_32 (RemainderBytes), Alignment.value ());
10396
+ ISD::LoadExtType ExtType = ISD::ZEXTLOAD;
10397
+ if (RemainderBytes + CurrBytes == NumBytes)
10398
+ ExtType = HiExtType;
10399
+
10400
+ SDValue CurrLD = DAG.getExtLoad (
10401
+ ExtType, dl, VT, Chain,
10402
+ DAG.getObjectPtrOffset (dl, Ptr, TypeSize::getFixed (PtrOffset)),
10403
+ LD->getPointerInfo ().getWithOffset (PtrOffset),
10404
+ EVT::getIntegerVT (*DAG.getContext (), CurrBytes * 8 ), BaseAlignment,
10405
+ LD->getMemOperand ()->getFlags (), LD->getAAInfo ());
10406
+ if (IsLE)
10407
+ Chains.push_back (CurrLD.getValue (1 ));
10408
+ else
10409
+ Chains.insert (Chains.begin (), CurrLD.getValue (1 ));
10410
+ SDValue CurrV = DAG.getNode (
10411
+ ISD::SHL, dl, VT, CurrLD,
10412
+ DAG.getShiftAmountConstant ((NumBytes - RemainderBytes) * 8 , VT, dl));
10413
+ Result = DAG.getNode (ISD::OR, dl, VT, CurrV, Result);
10414
+ RemainderBytes -= CurrBytes;
10415
+ if (RemainderBytes == 0 )
10416
+ break ;
10417
+ Alignment = commonAlignment (BaseAlignment,
10418
+ LD->getPointerInfo ().Offset + PtrOffset +
10419
+ (IsLE ? CurrBytes : -CurrBytes));
10420
+ PtrOffset =
10421
+ IsLE ? NumBytes - RemainderBytes : RemainderBytes - Alignment.value ();
10422
+ }
10423
+ SDValue TF = DAG.getNode (ISD::TokenFactor, dl, MVT::Other, Chains);
10424
+ return std::make_pair (Result, TF);
10425
+ }
10373
10426
// Compute the new VT that is half the size of the old one. This is an
10374
10427
// integer MVT.
10375
10428
unsigned NumBits = LoadedVT.getSizeInBits ();
10376
10429
EVT NewLoadedVT;
10377
10430
NewLoadedVT = EVT::getIntegerVT (*DAG.getContext (), NumBits/2 );
10378
10431
NumBits >>= 1 ;
10379
10432
10380
- Align Alignment = LD->getBaseAlign ();
10381
10433
unsigned IncrementSize = NumBits / 8 ;
10382
10434
ISD::LoadExtType HiExtType = LD->getExtensionType ();
10383
10435
@@ -10389,24 +10441,24 @@ TargetLowering::expandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG) const {
10389
10441
SDValue Lo, Hi;
10390
10442
if (DAG.getDataLayout ().isLittleEndian ()) {
10391
10443
Lo = DAG.getExtLoad (ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getPointerInfo (),
10392
- NewLoadedVT, Alignment, LD-> getMemOperand ()-> getFlags () ,
10393
- LD->getAAInfo ());
10444
+ NewLoadedVT, BaseAlignment ,
10445
+ LD->getMemOperand ()-> getFlags (), LD-> getAAInfo ());
10394
10446
10395
10447
Ptr = DAG.getObjectPtrOffset (dl, Ptr, TypeSize::getFixed (IncrementSize));
10396
10448
Hi = DAG.getExtLoad (HiExtType, dl, VT, Chain, Ptr,
10397
10449
LD->getPointerInfo ().getWithOffset (IncrementSize),
10398
- NewLoadedVT, Alignment, LD-> getMemOperand ()-> getFlags () ,
10399
- LD->getAAInfo ());
10450
+ NewLoadedVT, BaseAlignment ,
10451
+ LD->getMemOperand ()-> getFlags (), LD-> getAAInfo ());
10400
10452
} else {
10401
10453
Hi = DAG.getExtLoad (HiExtType, dl, VT, Chain, Ptr, LD->getPointerInfo (),
10402
- NewLoadedVT, Alignment, LD-> getMemOperand ()-> getFlags () ,
10403
- LD->getAAInfo ());
10454
+ NewLoadedVT, BaseAlignment ,
10455
+ LD->getMemOperand ()-> getFlags (), LD-> getAAInfo ());
10404
10456
10405
10457
Ptr = DAG.getObjectPtrOffset (dl, Ptr, TypeSize::getFixed (IncrementSize));
10406
10458
Lo = DAG.getExtLoad (ISD::ZEXTLOAD, dl, VT, Chain, Ptr,
10407
10459
LD->getPointerInfo ().getWithOffset (IncrementSize),
10408
- NewLoadedVT, Alignment, LD-> getMemOperand ()-> getFlags () ,
10409
- LD->getAAInfo ());
10460
+ NewLoadedVT, BaseAlignment ,
10461
+ LD->getMemOperand ()-> getFlags (), LD-> getAAInfo ());
10410
10462
}
10411
10463
10412
10464
// aggregate the two parts
@@ -10428,7 +10480,8 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
10428
10480
SDValue Ptr = ST->getBasePtr ();
10429
10481
SDValue Val = ST->getValue ();
10430
10482
EVT VT = Val.getValueType ();
10431
- Align Alignment = ST->getBaseAlign ();
10483
+ Align BaseAlignment = ST->getBaseAlign ();
10484
+ Align Alignment = ST->getAlign ();
10432
10485
auto &MF = DAG.getMachineFunction ();
10433
10486
EVT StoreMemVT = ST->getMemoryVT ();
10434
10487
@@ -10447,7 +10500,7 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
10447
10500
// FIXME: Does not handle truncating floating point stores!
10448
10501
SDValue Result = DAG.getNode (ISD::BITCAST, dl, intVT, Val);
10449
10502
Result = DAG.getStore (Chain, dl, Result, Ptr, ST->getPointerInfo (),
10450
- Alignment , ST->getMemOperand ()->getFlags ());
10503
+ BaseAlignment , ST->getMemOperand ()->getFlags ());
10451
10504
return Result;
10452
10505
}
10453
10506
// Do a (aligned) store to a stack slot, then copy from the stack slot
@@ -10515,6 +10568,47 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
10515
10568
10516
10569
assert (StoreMemVT.isInteger () && !StoreMemVT.isVector () &&
10517
10570
" Unaligned store of unknown type." );
10571
+
10572
+ // Divide the store value according to the latest align information
10573
+ if (commonAlignment (BaseAlignment,
10574
+ Alignment.value () + ST->getPointerInfo ().Offset ) >
10575
+ Alignment) {
10576
+ bool IsLE = DAG.getDataLayout ().isLittleEndian ();
10577
+ unsigned NumBytes = StoreMemVT.getFixedSizeInBits () / 8 ;
10578
+ SmallVector<SDValue, 8 > Stores;
10579
+ // LE/BE use the same initial Alignment
10580
+ unsigned PtrOffset = IsLE ? 0 : (NumBytes - Alignment.value ());
10581
+ unsigned RemainderBytes = NumBytes;
10582
+ while (RemainderBytes) {
10583
+ unsigned CurrBytes =
10584
+ std::min (1ul << Log2_32 (RemainderBytes), Alignment.value ());
10585
+ SDValue CurrST = DAG.getTruncStore (
10586
+ Chain, dl, Val,
10587
+ DAG.getObjectPtrOffset (dl, Ptr, TypeSize::getFixed (PtrOffset)),
10588
+ ST->getPointerInfo ().getWithOffset (PtrOffset),
10589
+ EVT::getIntegerVT (*DAG.getContext (), CurrBytes * 8 ), BaseAlignment,
10590
+ ST->getMemOperand ()->getFlags (), ST->getAAInfo ());
10591
+ if (IsLE)
10592
+ Stores.push_back (CurrST);
10593
+ else
10594
+ Stores.insert (Stores.begin (), CurrST);
10595
+ RemainderBytes -= CurrBytes;
10596
+ if (RemainderBytes == 0 )
10597
+ break ;
10598
+
10599
+ Val = DAG.getNode (ISD::SRL, dl, VT, Val,
10600
+ DAG.getShiftAmountConstant (CurrBytes * 8 , VT, dl));
10601
+ Alignment = commonAlignment (BaseAlignment,
10602
+ ST->getPointerInfo ().Offset + PtrOffset +
10603
+ (IsLE ? CurrBytes : -CurrBytes));
10604
+ PtrOffset =
10605
+ IsLE ? NumBytes - RemainderBytes : RemainderBytes - Alignment.value ();
10606
+ }
10607
+
10608
+ SDValue Result = DAG.getNode (ISD::TokenFactor, dl, MVT::Other, Stores);
10609
+ return Result;
10610
+ }
10611
+
10518
10612
// Get the half-size VT
10519
10613
EVT NewStoredVT = StoreMemVT.getHalfSizedIntegerVT (*DAG.getContext ());
10520
10614
unsigned NumBits = NewStoredVT.getFixedSizeInBits ();
@@ -10538,17 +10632,18 @@ SDValue TargetLowering::expandUnalignedStore(StoreSDNode *ST,
10538
10632
SDValue Store1, Store2;
10539
10633
Store1 = DAG.getTruncStore (Chain, dl,
10540
10634
DAG.getDataLayout ().isLittleEndian () ? Lo : Hi,
10541
- Ptr, ST->getPointerInfo (), NewStoredVT, Alignment,
10542
- ST->getMemOperand ()->getFlags ());
10635
+ Ptr, ST->getPointerInfo (), NewStoredVT,
10636
+ BaseAlignment, ST->getMemOperand ()->getFlags ());
10543
10637
10544
10638
Ptr = DAG.getObjectPtrOffset (dl, Ptr, TypeSize::getFixed (IncrementSize));
10545
10639
Store2 = DAG.getTruncStore (
10546
10640
Chain, dl, DAG.getDataLayout ().isLittleEndian () ? Hi : Lo, Ptr,
10547
- ST->getPointerInfo ().getWithOffset (IncrementSize), NewStoredVT, Alignment,
10548
- ST->getMemOperand ()->getFlags (), ST->getAAInfo ());
10641
+ ST->getPointerInfo ().getWithOffset (IncrementSize), NewStoredVT,
10642
+ BaseAlignment, ST->getMemOperand ()->getFlags (), ST->getAAInfo ());
10549
10643
10550
10644
SDValue Result =
10551
10645
DAG.getNode (ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
10646
+
10552
10647
return Result;
10553
10648
}
10554
10649
0 commit comments