diff options
author | Jessica Paquette <jpaquette@apple.com> | 2019-07-26 23:28:53 +0000 |
---|---|---|
committer | Jessica Paquette <jpaquette@apple.com> | 2019-07-26 23:28:53 +0000 |
commit | aa8b9993c23f9915f1ba694502333f67a627e8d0 (patch) | |
tree | 7a620a39ac88ac1fd39f18b1e1511313349ce7f7 /llvm/lib/Target | |
parent | f5a338369be46be25ed761617c00b7d9db45111e (diff) | |
download | bcm5719-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.cpp | 24 |
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); } |