summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorJessica Paquette <jpaquette@apple.com>2019-07-26 23:28:53 +0000
committerJessica Paquette <jpaquette@apple.com>2019-07-26 23:28:53 +0000
commitaa8b9993c23f9915f1ba694502333f67a627e8d0 (patch)
tree7a620a39ac88ac1fd39f18b1e1511313349ce7f7 /llvm/lib/Target
parentf5a338369be46be25ed761617c00b7d9db45111e (diff)
downloadbcm5719-llvm-aa8b9993c23f9915f1ba694502333f67a627e8d0.tar.gz
bcm5719-llvm-aa8b9993c23f9915f1ba694502333f67a627e8d0.zip
[AArch64][GlobalISel] Select @llvm.aarch64.stlxr for 32-bit pointers
Add partial instruction selection for intrinsics like this: ``` declare i32 @llvm.aarch64.stlxr(i64, i32*) ``` (This only handles the case where a G_ZEXT is feeding the intrinsic.) Also make sure that the added store instruction actually has the memory op from the original G_STORE. Update select-stlxr-intrin.mir and arm64-ldxr-stxr.ll. Differential Revision: https://reviews.llvm.org/D65355 llvm-svn: 367163
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 2a45ee662ef..4f2b4dc7f46 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -3892,7 +3892,9 @@ static unsigned findIntrinsicID(MachineInstr &I) {
/// intrinsic.
static unsigned getStlxrOpcode(unsigned NumBytesToStore) {
switch (NumBytesToStore) {
- // TODO: 1, 2, and 4 byte stores.
+ // TODO: 1 and 2 byte stores
+ case 4:
+ return AArch64::STLXRW;
case 8:
return AArch64::STLXRX;
default:
@@ -3946,8 +3948,24 @@ bool AArch64InstructionSelector::selectIntrinsicWithSideEffects(
unsigned Opc = getStlxrOpcode(NumBytesToStore);
if (!Opc)
return false;
-
- auto StoreMI = MIRBuilder.buildInstr(Opc, {StatReg}, {SrcReg, PtrReg});
+ unsigned NumBitsToStore = NumBytesToStore * 8;
+ if (NumBitsToStore != 64) {
+ // The intrinsic always has a 64-bit source, but we might actually want
+ // a differently-sized source for the instruction. Try to get it.
+ // TODO: For 1 and 2-byte stores, this will have a G_AND. For now, let's
+ // just handle 4-byte stores.
+ // TODO: If we don't find a G_ZEXT, we'll have to truncate the value down
+ // to the right size for the STLXR.
+ MachineInstr *Zext = getOpcodeDef(TargetOpcode::G_ZEXT, SrcReg, MRI);
+ if (!Zext)
+ return false;
+ SrcReg = Zext->getOperand(1).getReg();
+ // We should get an appropriately-sized register here.
+ if (RBI.getSizeInBits(SrcReg, MRI, TRI) != NumBitsToStore)
+ return false;
+ }
+ auto StoreMI = MIRBuilder.buildInstr(Opc, {StatReg}, {SrcReg, PtrReg})
+ .addMemOperand(*I.memoperands_begin());
constrainSelectedInstRegOperands(*StoreMI, TII, TRI, RBI);
}
OpenPOWER on IntegriCloud