Skip to content

Commit

Permalink
[AArch64] Preserve chain when lowering fixed length load to SVE (PR55…
Browse files Browse the repository at this point in the history
…281)

When a fixed length load is lowered to an SVE masked load, the
result chain is currently set to the input chain of the old load,
rather than the result chain of the new load. This may cause stores
to be incorrectly reordered.

Fixes #55281.

Differential Revision: https://reviews.llvm.org/D125464
  • Loading branch information
nikic committed May 12, 2022
1 parent 1474244 commit 44d8525
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
22 changes: 12 additions & 10 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Expand Up @@ -20140,22 +20140,23 @@ SDValue AArch64TargetLowering::LowerFixedLengthVectorLoadToSVE(
MemVT = MemVT.changeTypeToInteger();
}

auto NewLoad = DAG.getMaskedLoad(
SDValue NewLoad = DAG.getMaskedLoad(
LoadVT, DL, Load->getChain(), Load->getBasePtr(), Load->getOffset(), Pg,
DAG.getUNDEF(LoadVT), MemVT, Load->getMemOperand(),
Load->getAddressingMode(), Load->getExtensionType());

SDValue Result = NewLoad;
if (VT.isFloatingPoint() && Load->getExtensionType() == ISD::EXTLOAD) {
EVT ExtendVT = ContainerVT.changeVectorElementType(
Load->getMemoryVT().getVectorElementType());

NewLoad = getSVESafeBitCast(ExtendVT, NewLoad, DAG);
NewLoad = DAG.getNode(AArch64ISD::FP_EXTEND_MERGE_PASSTHRU, DL, ContainerVT,
Pg, NewLoad, DAG.getUNDEF(ContainerVT));
Result = getSVESafeBitCast(ExtendVT, Result, DAG);
Result = DAG.getNode(AArch64ISD::FP_EXTEND_MERGE_PASSTHRU, DL, ContainerVT,
Pg, Result, DAG.getUNDEF(ContainerVT));
}

auto Result = convertFromScalableVector(DAG, VT, NewLoad);
SDValue MergedValues[2] = {Result, Load->getChain()};
Result = convertFromScalableVector(DAG, VT, Result);
SDValue MergedValues[2] = {Result, NewLoad.getValue(1)};
return DAG.getMergeValues(MergedValues, DL);
}

Expand Down Expand Up @@ -20203,19 +20204,20 @@ SDValue AArch64TargetLowering::LowerFixedLengthVectorMLoadToSVE(
IsPassThruZeroOrUndef = true;
}

auto NewLoad = DAG.getMaskedLoad(
SDValue NewLoad = DAG.getMaskedLoad(
ContainerVT, DL, Load->getChain(), Load->getBasePtr(), Load->getOffset(),
Mask, PassThru, Load->getMemoryVT(), Load->getMemOperand(),
Load->getAddressingMode(), Load->getExtensionType());

SDValue Result = NewLoad;
if (!IsPassThruZeroOrUndef) {
SDValue OldPassThru =
convertToScalableVector(DAG, ContainerVT, Load->getPassThru());
NewLoad = DAG.getSelect(DL, ContainerVT, Mask, NewLoad, OldPassThru);
Result = DAG.getSelect(DL, ContainerVT, Mask, Result, OldPassThru);
}

auto Result = convertFromScalableVector(DAG, VT, NewLoad);
SDValue MergedValues[2] = {Result, Load->getChain()};
Result = convertFromScalableVector(DAG, VT, Result);
SDValue MergedValues[2] = {Result, NewLoad.getValue(1)};
return DAG.getMergeValues(MergedValues, DL);
}

Expand Down
Expand Up @@ -15,7 +15,7 @@ define void @foo(<8 x i64>* %a) #0 {
; CHECK-NEXT: t2: i64,ch = CopyFromReg t0, Register:i64 %0
; CHECK-NEXT: t18: nxv2i64,ch = LD1D_IMM<Mem:(volatile load (s512) from %ir.a)> t12, t2, TargetConstant:i64<0>, t0
; CHECK-NEXT: t8: i64 = ADDXri TargetFrameIndex:i64<1>, TargetConstant:i32<0>, TargetConstant:i32<0>
; CHECK-NEXT: t17: ch = ST1D_IMM<Mem:(volatile store (s512) into %ir.r0)> t18, t12, TargetFrameIndex:i64<0>, TargetConstant:i64<0>, t0
; CHECK-NEXT: t17: ch = ST1D_IMM<Mem:(volatile store (s512) into %ir.r0)> t18, t12, TargetFrameIndex:i64<0>, TargetConstant:i64<0>, t18:1
; CHECK-NEXT: t16: ch = ST1D_IMM<Mem:(volatile store (s512) into %ir.r1)> t18, t12, t8, TargetConstant:i64<0>, t17
; CHECK-NEXT: t10: ch = RET_ReallyLR t16
; CHECK-EMPTY:
Expand Down

0 comments on commit 44d8525

Please sign in to comment.