Skip to content

Commit 872ee78

Browse files
committed
Revert "[ARM] Improve codegen of volatile load/store of i64"
This reverts commit 8a12553. A bug has been found when generating code for Thumb2. In some very specific cases, the prologue/epilogue emitter generates erroneous stack offsets for the new LDRD instructions that access the stack. This bug does not seem to be caused by the reverted patch though. Likely the latter has made an undiscovered issue emerge in the prologue/epilogue emission pass. Nevertheless, this reversion is necessary since it is blocking users of the ARM backend.
1 parent b9def82 commit 872ee78

File tree

7 files changed

+6
-378
lines changed

7 files changed

+6
-378
lines changed

llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,24 +2735,6 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
27352735
MI.eraseFromParent();
27362736
return true;
27372737
}
2738-
case ARM::LOADDUAL:
2739-
case ARM::STOREDUAL: {
2740-
Register PairReg = MI.getOperand(0).getReg();
2741-
2742-
MachineInstrBuilder MIB =
2743-
BuildMI(MBB, MBBI, MI.getDebugLoc(),
2744-
TII->get(Opcode == ARM::LOADDUAL ? ARM::LDRD : ARM::STRD))
2745-
.addReg(TRI->getSubReg(PairReg, ARM::gsub_0),
2746-
Opcode == ARM::LOADDUAL ? RegState::Define : 0)
2747-
.addReg(TRI->getSubReg(PairReg, ARM::gsub_1),
2748-
Opcode == ARM::LOADDUAL ? RegState::Define : 0);
2749-
for (unsigned i = 1; i < MI.getNumOperands(); i++)
2750-
MIB.add(MI.getOperand(i));
2751-
MIB.add(predOps(ARMCC::AL));
2752-
MIB.cloneMemRefs(MI);
2753-
MI.eraseFromParent();
2754-
return true;
2755-
}
27562738
}
27572739
}
27582740

llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
145145

146146
// Thumb 2 Addressing Modes:
147147
bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
148-
template <unsigned Shift>
149-
bool SelectT2AddrModeImm8(SDValue N, SDValue &Base, SDValue &OffImm);
150148
bool SelectT2AddrModeImm8(SDValue N, SDValue &Base,
151149
SDValue &OffImm);
152150
bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
@@ -1314,33 +1312,6 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue N,
13141312
return true;
13151313
}
13161314

1317-
template <unsigned Shift>
1318-
bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N, SDValue &Base,
1319-
SDValue &OffImm) {
1320-
if (N.getOpcode() == ISD::SUB || CurDAG->isBaseWithConstantOffset(N)) {
1321-
int RHSC;
1322-
if (isScaledConstantInRange(N.getOperand(1), 1 << Shift, -255, 256, RHSC)) {
1323-
Base = N.getOperand(0);
1324-
if (Base.getOpcode() == ISD::FrameIndex) {
1325-
int FI = cast<FrameIndexSDNode>(Base)->getIndex();
1326-
Base = CurDAG->getTargetFrameIndex(
1327-
FI, TLI->getPointerTy(CurDAG->getDataLayout()));
1328-
}
1329-
1330-
if (N.getOpcode() == ISD::SUB)
1331-
RHSC = -RHSC;
1332-
OffImm =
1333-
CurDAG->getTargetConstant(RHSC * (1 << Shift), SDLoc(N), MVT::i32);
1334-
return true;
1335-
}
1336-
}
1337-
1338-
// Base only.
1339-
Base = N;
1340-
OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i32);
1341-
return true;
1342-
}
1343-
13441315
bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N,
13451316
SDValue &Base, SDValue &OffImm) {
13461317
// Match simple R - imm8 operands.
@@ -3684,59 +3655,6 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
36843655
CurDAG->RemoveDeadNode(N);
36853656
return;
36863657
}
3687-
case ARMISD::LDRD: {
3688-
if (Subtarget->isThumb2())
3689-
break; // TableGen handles isel in this case.
3690-
SDValue Base, RegOffset, ImmOffset;
3691-
const SDValue &Chain = N->getOperand(0);
3692-
const SDValue &Addr = N->getOperand(1);
3693-
SelectAddrMode3(Addr, Base, RegOffset, ImmOffset);
3694-
if (RegOffset != CurDAG->getRegister(0, MVT::i32)) {
3695-
// The register-offset variant of LDRD mandates that the register
3696-
// allocated to RegOffset is not reused in any of the remaining operands.
3697-
// This restriction is currently not enforced. Therefore emitting this
3698-
// variant is explicitly avoided.
3699-
Base = Addr;
3700-
RegOffset = CurDAG->getRegister(0, MVT::i32);
3701-
}
3702-
SDValue Ops[] = {Base, RegOffset, ImmOffset, Chain};
3703-
SDNode *New = CurDAG->getMachineNode(ARM::LOADDUAL, dl,
3704-
{MVT::Untyped, MVT::Other}, Ops);
3705-
SDValue Lo = CurDAG->getTargetExtractSubreg(ARM::gsub_0, dl, MVT::i32,
3706-
SDValue(New, 0));
3707-
SDValue Hi = CurDAG->getTargetExtractSubreg(ARM::gsub_1, dl, MVT::i32,
3708-
SDValue(New, 0));
3709-
transferMemOperands(N, New);
3710-
ReplaceUses(SDValue(N, 0), Lo);
3711-
ReplaceUses(SDValue(N, 1), Hi);
3712-
ReplaceUses(SDValue(N, 2), SDValue(New, 1));
3713-
CurDAG->RemoveDeadNode(N);
3714-
return;
3715-
}
3716-
case ARMISD::STRD: {
3717-
if (Subtarget->isThumb2())
3718-
break; // TableGen handles isel in this case.
3719-
SDValue Base, RegOffset, ImmOffset;
3720-
const SDValue &Chain = N->getOperand(0);
3721-
const SDValue &Addr = N->getOperand(3);
3722-
SelectAddrMode3(Addr, Base, RegOffset, ImmOffset);
3723-
if (RegOffset != CurDAG->getRegister(0, MVT::i32)) {
3724-
// The register-offset variant of STRD mandates that the register
3725-
// allocated to RegOffset is not reused in any of the remaining operands.
3726-
// This restriction is currently not enforced. Therefore emitting this
3727-
// variant is explicitly avoided.
3728-
Base = Addr;
3729-
RegOffset = CurDAG->getRegister(0, MVT::i32);
3730-
}
3731-
SDNode *RegPair =
3732-
createGPRPairNode(MVT::Untyped, N->getOperand(1), N->getOperand(2));
3733-
SDValue Ops[] = {SDValue(RegPair, 0), Base, RegOffset, ImmOffset, Chain};
3734-
SDNode *New = CurDAG->getMachineNode(ARM::STOREDUAL, dl, MVT::Other, Ops);
3735-
transferMemOperands(N, New);
3736-
ReplaceUses(SDValue(N, 0), SDValue(New, 0));
3737-
CurDAG->RemoveDeadNode(N);
3738-
return;
3739-
}
37403658
case ARMISD::LOOP_DEC: {
37413659
SDValue Ops[] = { N->getOperand(1),
37423660
N->getOperand(2),

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,8 +1082,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
10821082
setOperationAction(ISD::SRA, MVT::i64, Custom);
10831083
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
10841084
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
1085-
setOperationAction(ISD::LOAD, MVT::i64, Custom);
1086-
setOperationAction(ISD::STORE, MVT::i64, Custom);
10871085

10881086
// MVE lowers 64 bit shifts to lsll and lsrl
10891087
// assuming that ISD::SRL and SRA of i64 are already marked custom
@@ -1626,9 +1624,6 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
16261624

16271625
case ARMISD::PRELOAD: return "ARMISD::PRELOAD";
16281626

1629-
case ARMISD::LDRD: return "ARMISD::LDRD";
1630-
case ARMISD::STRD: return "ARMISD::STRD";
1631-
16321627
case ARMISD::WIN__CHKSTK: return "ARMISD::WIN__CHKSTK";
16331628
case ARMISD::WIN__DBZCHK: return "ARMISD::WIN__DBZCHK";
16341629

@@ -9156,25 +9151,6 @@ static SDValue LowerPredicateLoad(SDValue Op, SelectionDAG &DAG) {
91569151
return DAG.getMergeValues({Pred, Load.getValue(1)}, dl);
91579152
}
91589153

9159-
void ARMTargetLowering::LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
9160-
SelectionDAG &DAG) const {
9161-
LoadSDNode *LD = cast<LoadSDNode>(N);
9162-
EVT MemVT = LD->getMemoryVT();
9163-
assert(LD->isUnindexed() && "Loads should be unindexed at this point.");
9164-
9165-
if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
9166-
!Subtarget->isThumb1Only() && LD->isVolatile()) {
9167-
SDLoc dl(N);
9168-
SDValue Result = DAG.getMemIntrinsicNode(
9169-
ARMISD::LDRD, dl, DAG.getVTList({MVT::i32, MVT::i32, MVT::Other}),
9170-
{LD->getChain(), LD->getBasePtr()}, MemVT, LD->getMemOperand());
9171-
SDValue Lo = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 0 : 1);
9172-
SDValue Hi = Result.getValue(DAG.getDataLayout().isLittleEndian() ? 1 : 0);
9173-
SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
9174-
Results.append({Pair, Result.getValue(2)});
9175-
}
9176-
}
9177-
91789154
static SDValue LowerPredicateStore(SDValue Op, SelectionDAG &DAG) {
91799155
StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
91809156
EVT MemVT = ST->getMemoryVT();
@@ -9204,38 +9180,6 @@ static SDValue LowerPredicateStore(SDValue Op, SelectionDAG &DAG) {
92049180
ST->getMemOperand());
92059181
}
92069182

9207-
static SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG,
9208-
const ARMSubtarget *Subtarget) {
9209-
StoreSDNode *ST = cast<StoreSDNode>(Op.getNode());
9210-
EVT MemVT = ST->getMemoryVT();
9211-
assert(ST->isUnindexed() && "Stores should be unindexed at this point.");
9212-
9213-
if (MemVT == MVT::i64 && Subtarget->hasV5TEOps() &&
9214-
!Subtarget->isThumb1Only() && ST->isVolatile()) {
9215-
SDNode *N = Op.getNode();
9216-
SDLoc dl(N);
9217-
9218-
SDValue Lo = DAG.getNode(
9219-
ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
9220-
DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 0 : 1, dl,
9221-
MVT::i32));
9222-
SDValue Hi = DAG.getNode(
9223-
ISD::EXTRACT_ELEMENT, dl, MVT::i32, ST->getValue(),
9224-
DAG.getTargetConstant(DAG.getDataLayout().isLittleEndian() ? 1 : 0, dl,
9225-
MVT::i32));
9226-
9227-
return DAG.getMemIntrinsicNode(ARMISD::STRD, dl, DAG.getVTList(MVT::Other),
9228-
{ST->getChain(), Lo, Hi, ST->getBasePtr()},
9229-
MemVT, ST->getMemOperand());
9230-
} else if (Subtarget->hasMVEIntegerOps() &&
9231-
((MemVT == MVT::v4i1 || MemVT == MVT::v8i1 ||
9232-
MemVT == MVT::v16i1))) {
9233-
return LowerPredicateStore(Op, DAG);
9234-
}
9235-
9236-
return SDValue();
9237-
}
9238-
92399183
static bool isZeroVector(SDValue N) {
92409184
return (ISD::isBuildVectorAllZeros(N.getNode()) ||
92419185
(N->getOpcode() == ARMISD::VMOVIMM &&
@@ -9470,7 +9414,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
94709414
case ISD::LOAD:
94719415
return LowerPredicateLoad(Op, DAG);
94729416
case ISD::STORE:
9473-
return LowerSTORE(Op, DAG, Subtarget);
9417+
return LowerPredicateStore(Op, DAG);
94749418
case ISD::MLOAD:
94759419
return LowerMLOAD(Op, DAG);
94769420
case ISD::ATOMIC_LOAD:
@@ -9574,9 +9518,7 @@ void ARMTargetLowering::ReplaceNodeResults(SDNode *N,
95749518
case ISD::ABS:
95759519
lowerABS(N, Results, DAG);
95769520
return ;
9577-
case ISD::LOAD:
9578-
LowerLOAD(N, Results, DAG);
9579-
break;
9521+
95809522
}
95819523
if (Res.getNode())
95829524
Results.push_back(Res);

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,7 @@ class VectorType;
305305
VST4_UPD,
306306
VST2LN_UPD,
307307
VST3LN_UPD,
308-
VST4LN_UPD,
309-
310-
// Load/Store of dual registers
311-
LDRD,
312-
STRD
308+
VST4LN_UPD
313309
};
314310

315311
} // end namespace ARMISD
@@ -775,8 +771,6 @@ class VectorType;
775771
SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
776772
void lowerABS(SDNode *N, SmallVectorImpl<SDValue> &Results,
777773
SelectionDAG &DAG) const;
778-
void LowerLOAD(SDNode *N, SmallVectorImpl<SDValue> &Results,
779-
SelectionDAG &DAG) const;
780774

781775
Register getRegisterByName(const char* RegName, LLT VT,
782776
const MachineFunction &MF) const override;

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,6 @@ def ARMqsub8b : SDNode<"ARMISD::QSUB8b", SDT_ARMAnd, []>;
245245
def ARMqadd16b : SDNode<"ARMISD::QADD16b", SDT_ARMAnd, []>;
246246
def ARMqsub16b : SDNode<"ARMISD::QSUB16b", SDT_ARMAnd, []>;
247247

248-
def SDT_ARMldrd : SDTypeProfile<2, 1, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>;
249-
def ARMldrd : SDNode<"ARMISD::LDRD", SDT_ARMldrd, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
250-
251-
def SDT_ARMstrd : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>;
252-
def ARMstrd : SDNode<"ARMISD::STRD", SDT_ARMstrd, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
253-
254248
// Vector operations shared between NEON and MVE
255249

256250
def ARMvdup : SDNode<"ARMISD::VDUP", SDTypeProfile<1, 1, [SDTCisVec<0>]>>;
@@ -2742,14 +2736,6 @@ let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
27422736
Requires<[IsARM, HasV5TE]>;
27432737
}
27442738

2745-
let mayLoad = 1, hasSideEffects = 0, hasNoSchedulingInfo = 1 in {
2746-
def LOADDUAL : ARMPseudoInst<(outs GPRPairOp:$Rt), (ins addrmode3:$addr),
2747-
64, IIC_iLoad_d_r, []>,
2748-
Requires<[IsARM, HasV5TE]> {
2749-
let AM = AddrMode3;
2750-
}
2751-
}
2752-
27532739
def LDA : AIldracq<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr),
27542740
NoItinerary, "lda", "\t$Rt, $addr", []>;
27552741
def LDAB : AIldracq<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr),
@@ -3028,14 +3014,6 @@ let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in {
30283014
}
30293015
}
30303016

3031-
let mayStore = 1, hasSideEffects = 0, hasNoSchedulingInfo = 1 in {
3032-
def STOREDUAL : ARMPseudoInst<(outs), (ins GPRPairOp:$Rt, addrmode3:$addr),
3033-
64, IIC_iStore_d_r, []>,
3034-
Requires<[IsARM, HasV5TE]> {
3035-
let AM = AddrMode3;
3036-
}
3037-
}
3038-
30393017
// Indexed stores
30403018
multiclass AI2_stridx<bit isByte, string opc,
30413019
InstrItinClass iii, InstrItinClass iir> {

llvm/lib/Target/ARM/ARMInstrThumb2.td

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,7 @@ def t2am_imm8_offset : MemOperand,
270270

271271
// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
272272
def MemImm8s4OffsetAsmOperand : AsmOperandClass {let Name = "MemImm8s4Offset";}
273-
class T2AddrMode_Imm8s4 : MemOperand,
274-
ComplexPattern<i32, 2, "SelectT2AddrModeImm8<2>", []> {
273+
class T2AddrMode_Imm8s4 : MemOperand {
275274
let EncoderMethod = "getT2AddrModeImm8s4OpValue";
276275
let DecoderMethod = "DecodeT2AddrModeImm8s4";
277276
let ParserMatchClass = MemImm8s4OffsetAsmOperand;
@@ -1449,8 +1448,7 @@ let mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1 in {
14491448
// Load doubleword
14501449
def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2),
14511450
(ins t2addrmode_imm8s4:$addr),
1452-
IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", "",
1453-
[(set rGPR:$Rt, rGPR:$Rt2, (ARMldrd t2addrmode_imm8s4:$addr))]>,
1451+
IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", "", []>,
14541452
Sched<[WriteLd]>;
14551453
} // mayLoad = 1, hasSideEffects = 0, hasExtraDefRegAllocReq = 1
14561454

@@ -1631,8 +1629,7 @@ defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si,
16311629
let mayStore = 1, hasSideEffects = 0, hasExtraSrcRegAllocReq = 1 in
16321630
def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs),
16331631
(ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4:$addr),
1634-
IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", "",
1635-
[(ARMstrd rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4:$addr)]>,
1632+
IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", "", []>,
16361633
Sched<[WriteST]>;
16371634

16381635
// Indexed stores

0 commit comments

Comments
 (0)