[llvm-branch-commits] [llvm] 7ec8f43 - [SPARC] Fix fp128 load/stores
Craig Topper via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jan 13 15:07:24 PST 2021
Author: Craig Topper
Date: 2021-01-13T14:59:50-08:00
New Revision: 7ec8f43659861be42f9d600422678196849b6e90
URL: https://github.com/llvm/llvm-project/commit/7ec8f43659861be42f9d600422678196849b6e90
DIFF: https://github.com/llvm/llvm-project/commit/7ec8f43659861be42f9d600422678196849b6e90.diff
LOG: [SPARC] Fix fp128 load/stores
The generated code for the split fp128 load/stores was missing a small yet important adjustment to the pointer metadata being fed into `getStore` and `getLoad`, making it out of sync with the effective memory address.
This problem often resulted in instructions being scheduled in the wrong order.
I also took this chance to clean up some "wrong" uses of `getAlignment` as done in D77687.
Thanks @jrtc27 for finding the problem and providing a patch.
Patch by LemonBoy and Jessica Clarke(jrtc27)
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D94345
Added:
llvm/test/CodeGen/SPARC/fp128-split.ll
Modified:
llvm/lib/Target/Sparc/SparcISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 415c2bed6dd5..e5c7794b7d2f 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -2733,23 +2733,21 @@ static SDValue LowerF64Op(SDValue SrcReg64, const SDLoc &dl, SelectionDAG &DAG,
static SDValue LowerF128Load(SDValue Op, SelectionDAG &DAG)
{
SDLoc dl(Op);
- LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode());
- assert(LdNode && LdNode->getOffset().isUndef()
- && "Unexpected node type");
+ LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
+ assert(LdNode->getOffset().isUndef() && "Unexpected node type");
- unsigned alignment = LdNode->getAlignment();
- if (alignment > 8)
- alignment = 8;
+ Align Alignment = commonAlignment(LdNode->getOriginalAlign(), 8);
SDValue Hi64 =
DAG.getLoad(MVT::f64, dl, LdNode->getChain(), LdNode->getBasePtr(),
- LdNode->getPointerInfo(), alignment);
+ LdNode->getPointerInfo(), Alignment);
EVT addrVT = LdNode->getBasePtr().getValueType();
SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT,
LdNode->getBasePtr(),
DAG.getConstant(8, dl, addrVT));
SDValue Lo64 = DAG.getLoad(MVT::f64, dl, LdNode->getChain(), LoPtr,
- LdNode->getPointerInfo(), alignment);
+ LdNode->getPointerInfo().getWithOffset(8),
+ Alignment);
SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, dl, MVT::i32);
SDValue SubRegOdd = DAG.getTargetConstant(SP::sub_odd64, dl, MVT::i32);
@@ -2787,9 +2785,9 @@ static SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG)
// Lower a f128 store into two f64 stores.
static SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG) {
SDLoc dl(Op);
- StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode());
- assert(StNode && StNode->getOffset().isUndef()
- && "Unexpected node type");
+ StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode());
+ assert(StNode->getOffset().isUndef() && "Unexpected node type");
+
SDValue SubRegEven = DAG.getTargetConstant(SP::sub_even64, dl, MVT::i32);
SDValue SubRegOdd = DAG.getTargetConstant(SP::sub_odd64, dl, MVT::i32);
@@ -2804,20 +2802,20 @@ static SDValue LowerF128Store(SDValue Op, SelectionDAG &DAG) {
StNode->getValue(),
SubRegOdd);
- unsigned alignment = StNode->getAlignment();
- if (alignment > 8)
- alignment = 8;
+ Align Alignment = commonAlignment(StNode->getOriginalAlign(), 8);
SDValue OutChains[2];
OutChains[0] =
DAG.getStore(StNode->getChain(), dl, SDValue(Hi64, 0),
- StNode->getBasePtr(), MachinePointerInfo(), alignment);
+ StNode->getBasePtr(), StNode->getPointerInfo(),
+ Alignment);
EVT addrVT = StNode->getBasePtr().getValueType();
SDValue LoPtr = DAG.getNode(ISD::ADD, dl, addrVT,
StNode->getBasePtr(),
DAG.getConstant(8, dl, addrVT));
OutChains[1] = DAG.getStore(StNode->getChain(), dl, SDValue(Lo64, 0), LoPtr,
- MachinePointerInfo(), alignment);
+ StNode->getPointerInfo().getWithOffset(8),
+ Alignment);
return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
}
@@ -2836,7 +2834,8 @@ static SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG)
SDValue Val = DAG.getNode(ISD::BITCAST, dl, MVT::v2i32, St->getValue());
SDValue Chain = DAG.getStore(
St->getChain(), dl, Val, St->getBasePtr(), St->getPointerInfo(),
- St->getAlignment(), St->getMemOperand()->getFlags(), St->getAAInfo());
+ St->getOriginalAlign(), St->getMemOperand()->getFlags(),
+ St->getAAInfo());
return Chain;
}
@@ -3402,8 +3401,9 @@ void SparcTargetLowering::ReplaceNodeResults(SDNode *N,
SDLoc dl(N);
SDValue LoadRes = DAG.getExtLoad(
Ld->getExtensionType(), dl, MVT::v2i32, Ld->getChain(),
- Ld->getBasePtr(), Ld->getPointerInfo(), MVT::v2i32, Ld->getAlignment(),
- Ld->getMemOperand()->getFlags(), Ld->getAAInfo());
+ Ld->getBasePtr(), Ld->getPointerInfo(), MVT::v2i32,
+ Ld->getOriginalAlign(), Ld->getMemOperand()->getFlags(),
+ Ld->getAAInfo());
SDValue Res = DAG.getNode(ISD::BITCAST, dl, MVT::i64, LoadRes);
Results.push_back(Res);
diff --git a/llvm/test/CodeGen/SPARC/fp128-split.ll b/llvm/test/CodeGen/SPARC/fp128-split.ll
new file mode 100644
index 000000000000..6a241ea11bb4
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/fp128-split.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -mtriple=sparcv9-unknown-linux -verify-machineinstrs -stop-after=finalize-isel < %s | FileCheck %s
+
+; Check that the fp128 load/store is correctly split.
+; The pointer metadata for the upper/lower halves of the load/store should be in
+; sync with the OP address.
+
+define fp128 @testcase(fp128 %0) {
+ ; CHECK-LABEL: name: testcase
+ ; CHECK: bb.0.Entry:
+ ; CHECK: liveins: $q0
+ ; CHECK: [[COPY:%[0-9]+]]:qfpregs = COPY $q0
+ ; CHECK: [[COPY1:%[0-9]+]]:dfpregs = COPY [[COPY]].sub_odd64
+ ; CHECK: [[LEAX_ADDri:%[0-9]+]]:i64regs = LEAX_ADDri %stack.0, 0
+ ; CHECK: [[ORXri:%[0-9]+]]:i64regs = ORXri killed [[LEAX_ADDri]], 8
+ ; CHECK: STDFrr [[ORXri]], $g0, killed [[COPY1]] :: (store 8 into %stack.0 + 8)
+ ; CHECK: [[COPY2:%[0-9]+]]:dfpregs = COPY [[COPY]].sub_even64
+ ; CHECK: STDFri %stack.0, 0, killed [[COPY2]] :: (store 8 into %stack.0, align 16)
+ ; CHECK: [[LDXrr:%[0-9]+]]:i64regs = LDXrr [[ORXri]], $g0 :: (load 8 from %stack.0 + 8)
+ ; CHECK: [[LDXri:%[0-9]+]]:i64regs = LDXri %stack.0, 0 :: (load 8 from %stack.0, align 16)
+ ; CHECK: [[COPY3:%[0-9]+]]:intregs = COPY [[LDXrr]]
+ ; CHECK: [[COPY4:%[0-9]+]]:intregs = COPY [[LDXri]]
+ ; CHECK: [[SRLXri:%[0-9]+]]:i64regs = SRLXri [[LDXrr]], 32
+ ; CHECK: [[COPY5:%[0-9]+]]:intregs = COPY [[SRLXri]]
+ ; CHECK: [[SRLXri1:%[0-9]+]]:i64regs = SRLXri [[LDXri]], 32
+ ; CHECK: [[COPY6:%[0-9]+]]:intregs = COPY [[SRLXri1]]
+ ; CHECK: [[ADDCCri:%[0-9]+]]:intregs = ADDCCri killed [[COPY3]], -1, implicit-def $icc
+ ; CHECK: [[ADDEri:%[0-9]+]]:intregs = ADDEri killed [[COPY5]], -1, implicit-def $icc, implicit $icc
+ ; CHECK: [[ADDEri1:%[0-9]+]]:intregs = ADDEri killed [[COPY4]], -1, implicit-def $icc, implicit $icc
+ ; CHECK: [[ADDEri2:%[0-9]+]]:intregs = ADDEri killed [[COPY6]], -1, implicit-def dead $icc, implicit $icc
+ ; CHECK: [[SRLri:%[0-9]+]]:i64regs = SRLri killed [[ADDCCri]], 0
+ ; CHECK: [[COPY7:%[0-9]+]]:i64regs = COPY [[ADDEri]]
+ ; CHECK: [[SLLXri:%[0-9]+]]:i64regs = SLLXri killed [[COPY7]], 32
+ ; CHECK: [[ORXrr:%[0-9]+]]:i64regs = ORXrr killed [[SLLXri]], killed [[SRLri]]
+ ; CHECK: [[LEAX_ADDri1:%[0-9]+]]:i64regs = LEAX_ADDri %stack.1, 0
+ ; CHECK: [[ORXri1:%[0-9]+]]:i64regs = ORXri killed [[LEAX_ADDri1]], 8
+ ; CHECK: STXrr [[ORXri1]], $g0, killed [[ORXrr]] :: (store 8 into %stack.1 + 8, basealign 16)
+ ; CHECK: [[SRLri1:%[0-9]+]]:i64regs = SRLri killed [[ADDEri1]], 0
+ ; CHECK: [[COPY8:%[0-9]+]]:i64regs = COPY [[ADDEri2]]
+ ; CHECK: [[SLLXri1:%[0-9]+]]:i64regs = SLLXri killed [[COPY8]], 32
+ ; CHECK: [[ORXrr1:%[0-9]+]]:i64regs = ORXrr killed [[SLLXri1]], killed [[SRLri1]]
+ ; CHECK: STXri %stack.1, 0, killed [[ORXrr1]] :: (store 8 into %stack.1, align 16)
+ ; CHECK: [[LDDFri:%[0-9]+]]:dfpregs = LDDFri %stack.1, 0 :: (load 8 from %stack.1, align 16)
+ ; CHECK: [[DEF:%[0-9]+]]:qfpregs = IMPLICIT_DEF
+ ; CHECK: [[INSERT_SUBREG:%[0-9]+]]:qfpregs = INSERT_SUBREG [[DEF]], killed [[LDDFri]], %subreg.sub_even64
+ ; CHECK: [[LDDFrr:%[0-9]+]]:dfpregs = LDDFrr [[ORXri1]], $g0 :: (load 8 from %stack.1 + 8)
+ ; CHECK: [[INSERT_SUBREG1:%[0-9]+]]:qfpregs = INSERT_SUBREG [[INSERT_SUBREG]], killed [[LDDFrr]], %subreg.sub_odd64
+ ; CHECK: $q0 = COPY [[INSERT_SUBREG1]]
+ ; CHECK: RETL 8, implicit $q0
+Entry:
+ %1 = bitcast fp128 %0 to i128
+ %2 = add i128 %1, -1
+ %3 = bitcast i128 %2 to fp128
+ ret fp128 %3
+}
More information about the llvm-branch-commits
mailing list