From 44d85259d0187c4674e91bd888ed0ccddd4a5ab5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 12 May 2022 14:56:44 +0200 Subject: [PATCH] [AArch64] Preserve chain when lowering fixed length load to SVE (PR55281) 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 https://github.com/llvm/llvm-project/issues/55281. Differential Revision: https://reviews.llvm.org/D125464 --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 22 ++++++++++++---------- .../AArch64/sve-fixed-length-frame-offests.ll | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 7bc0daa..c10303b 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -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); } @@ -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); } diff --git a/llvm/test/CodeGen/AArch64/sve-fixed-length-frame-offests.ll b/llvm/test/CodeGen/AArch64/sve-fixed-length-frame-offests.ll index 9227c4c..98ae39c 100644 --- a/llvm/test/CodeGen/AArch64/sve-fixed-length-frame-offests.ll +++ b/llvm/test/CodeGen/AArch64/sve-fixed-length-frame-offests.ll @@ -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 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 t18, t12, TargetFrameIndex:i64<0>, TargetConstant:i64<0>, t0 +; CHECK-NEXT: t17: ch = ST1D_IMM t18, t12, TargetFrameIndex:i64<0>, TargetConstant:i64<0>, t18:1 ; CHECK-NEXT: t16: ch = ST1D_IMM t18, t12, t8, TargetConstant:i64<0>, t17 ; CHECK-NEXT: t10: ch = RET_ReallyLR t16 ; CHECK-EMPTY: -- 2.7.4