Skip to content

Commit ef5f51f

Browse files
committed
atomic_compare_exchange_weak
1 parent 06ee672 commit ef5f51f

File tree

6 files changed

+111
-4
lines changed

6 files changed

+111
-4
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ class TargetLoweringBase {
257257
CastToInteger, // Cast the atomic instruction to another type, e.g. from
258258
// floating-point to integer type.
259259
LLSC, // Expand the instruction into loadlinked/storeconditional; used
260-
// by ARM/AArch64.
260+
// by ARM/AArch64/PowerPC.
261261
LLOnly, // Expand the (load) instruction into just a load-linked, which has
262262
// greater atomic guarantees than a normal load.
263263
CmpXChg, // Expand the instruction into cmpxchg; used by at least X86.

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,23 @@ let TargetPrefix = "ppc" in {
18351835
Intrinsic<[],[],[]>;
18361836
def int_ppc_iospace_eieio : ClangBuiltin<"__builtin_ppc_iospace_eieio">,
18371837
Intrinsic<[],[],[]>;
1838+
def int_ppc_lbarx :
1839+
ClangBuiltin<"__builtin_ppc_lbarx">,
1840+
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty],
1841+
[IntrReadMem, IntrArgMemOnly, IntrNoDuplicate]>;
1842+
def int_ppc_lharx :
1843+
ClangBuiltin<"__builtin_ppc_lharx">,
1844+
Intrinsic<[llvm_i32_ty],[llvm_ptr_ty],
1845+
[IntrReadMem, IntrArgMemOnly, IntrNoDuplicate]>;
1846+
def int_ppc_lwarx :
1847+
ClangBuiltin<"__builtin_ppc_lwarx">,
1848+
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty],
1849+
[IntrReadMem, IntrArgMemOnly, IntrNoDuplicate]>;
1850+
def int_ppc_ldarx :
1851+
ClangBuiltin<"__builtin_ppc_ldarx">,
1852+
Intrinsic<[llvm_i64_ty],[llvm_ptr_ty],
1853+
[IntrReadMem, IntrArgMemOnly, IntrNoDuplicate]>;
1854+
18381855
def int_ppc_stdcx :
18391856
ClangBuiltin<"__builtin_ppc_stdcx">,
18401857
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i64_ty],
@@ -1844,7 +1861,7 @@ let TargetPrefix = "ppc" in {
18441861
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
18451862
[IntrWriteMem, IntrArgMemOnly]>;
18461863
def int_ppc_sthcx :
1847-
Intrinsic<[llvm_i32_ty], [ llvm_ptr_ty, llvm_i32_ty ],
1864+
Intrinsic<[llvm_i32_ty], [ llvm_ptr_ty, llvm_i32_ty],
18481865
[IntrWriteMem, IntrArgMemOnly, IntrNoDuplicate]>;
18491866
def int_ppc_stbcx :
18501867
ClangBuiltin<"__builtin_ppc_stbcx">,

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
14751475
setMinimumJumpTableEntries(PPCMinimumJumpTableEntries);
14761476

14771477
setMinFunctionAlignment(Align(4));
1478+
if(Subtarget.hasPartwordAtomics())
1479+
setMinCmpXchgSizeInBits(8);
1480+
else
1481+
setMinCmpXchgSizeInBits(32);
14781482

14791483
switch (Subtarget.getCPUDirective()) {
14801484
default: break;
@@ -12672,6 +12676,77 @@ static Instruction *callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id) {
1267212676
return Builder.CreateIntrinsic(Id, {});
1267312677
}
1267412678

12679+
Value *PPCTargetLowering::emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy,
12680+
Value *Addr,
12681+
AtomicOrdering Ord) const {
12682+
unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12683+
12684+
assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12685+
+"Only 8/16/32/64-bit atomic loads supported");
12686+
Intrinsic::ID IntID;
12687+
switch (SZ) {
12688+
default:
12689+
llvm_unreachable("Unexpected PrimitiveSize");
12690+
case 8:
12691+
IntID = Intrinsic::ppc_lbarx;
12692+
assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
12693+
break;
12694+
case 16:
12695+
IntID = Intrinsic::ppc_lharx;
12696+
assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
12697+
break;
12698+
case 32:
12699+
IntID = Intrinsic::ppc_lwarx;
12700+
break;
12701+
case 64:
12702+
IntID = Intrinsic::ppc_ldarx;
12703+
break;
12704+
}
12705+
Value *Call =
12706+
Builder.CreateIntrinsic(IntID, Addr, /*FMFSource=*/nullptr, "larx");
12707+
12708+
return Builder.CreateTruncOrBitCast(Call, ValueTy);
12709+
}
12710+
12711+
// Perform a store-conditional operation to Addr. Return the status of the
12712+
// store. This should be 0 if the store succeeded, non-zero otherwise.
12713+
Value *PPCTargetLowering::emitStoreConditional(IRBuilderBase &Builder,
12714+
Value *Val, Value *Addr,
12715+
AtomicOrdering Ord) const {
12716+
Type *Ty = Val->getType();
12717+
unsigned SZ = Ty->getPrimitiveSizeInBits();
12718+
12719+
assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12720+
"Only 8/16/32/64-bit atomic loads supported");
12721+
Intrinsic::ID IntID;
12722+
switch (SZ) {
12723+
default:
12724+
llvm_unreachable("Unexpected PrimitiveSize");
12725+
case 8:
12726+
IntID = Intrinsic::ppc_stbcx;
12727+
assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
12728+
break;
12729+
case 16:
12730+
IntID = Intrinsic::ppc_sthcx;
12731+
assert(Subtarget.hasPartwordAtomics() && "No support partword atomics.");
12732+
break;
12733+
case 32:
12734+
IntID = Intrinsic::ppc_stwcx;
12735+
break;
12736+
case 64:
12737+
IntID = Intrinsic::ppc_stdcx;
12738+
break;
12739+
}
12740+
12741+
if(SZ ==8 || SZ==16)
12742+
Val = Builder.CreateZExt(Val, Builder.getIntNTy(32));;
12743+
12744+
Value *Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
12745+
/*FMFSource=*/nullptr, "stcx");
12746+
Value *Not = Builder.CreateXor(Call,Builder.getInt32(1));
12747+
return Not;
12748+
}
12749+
1267512750
// The mappings for emitLeading/TrailingFence is taken from
1267612751
// http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
1267712752
Instruction *PPCTargetLowering::emitLeadingFence(IRBuilderBase &Builder,
@@ -19633,7 +19708,8 @@ PPCTargetLowering::shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const {
1963319708
unsigned Size = AI->getNewValOperand()->getType()->getPrimitiveSizeInBits();
1963419709
if (shouldInlineQuadwordAtomics() && Size == 128)
1963519710
return AtomicExpansionKind::MaskedIntrinsic;
19636-
return TargetLowering::shouldExpandAtomicCmpXchgInIR(AI);
19711+
return AtomicExpansionKind::LLSC;
19712+
//return TargetLowering::shouldExpandAtomicCmpXchgInIR(AI);
1963719713
}
1963819714

1963919715
static Intrinsic::ID

llvm/lib/Target/PowerPC/PPCISelLowering.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,12 @@ namespace llvm {
927927
return true;
928928
}
929929

930+
Value *emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr,
931+
AtomicOrdering Ord) const override;
932+
933+
Value *emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr,
934+
AtomicOrdering Ord) const override;
935+
930936
Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst,
931937
AtomicOrdering Ord) const override;
932938
Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst,

llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,8 @@ def SLBSYNC : XForm_0<31, 338, (outs), (ins), "slbsync", IIC_SprSLBSYNC, []>;
20232023

20242024
} // IsISA3_0
20252025

2026+
def : Pat<(int_ppc_ldarx ForceXForm:$ptr),
2027+
(LDARX ForceXForm:$ptr)>;
20262028
def : Pat<(int_ppc_stdcx ForceXForm:$dst, g8rc:$A),
20272029
(RLWINM (STDCX g8rc:$A, ForceXForm:$dst), 31, 31, 31)>;
20282030
def : Pat<(PPCStoreCond ForceXForm:$dst, g8rc:$A, 8),

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5143,7 +5143,6 @@ def : Pat<(int_ppc_store2r gprc:$a, ForceXForm:$ptr),
51435143
def : Pat<(int_ppc_store4r gprc:$a, ForceXForm:$ptr),
51445144
(STWBRX gprc:$a, ForceXForm:$ptr)>;
51455145

5146-
51475146
// Fast 32-bit reverse bits algorithm:
51485147
// Step 1: 1-bit swap (swap odd 1-bit and even 1-bit):
51495148
// n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xAAAAAAAA);
@@ -5324,10 +5323,14 @@ def CFENCE : PPCPostRAExpPseudo<(outs), (ins gprc:$cr), "#CFENCE", []>;
53245323
def : Pat<(i64 (bitreverse i64:$A)),
53255324
(OR8 (RLDICR DWBytes7654.DWord, 32, 31), DWBytes3210.DWord)>;
53265325

5326+
def : Pat<(int_ppc_lwarx ForceXForm:$ptr),
5327+
(LWARX ForceXForm:$ptr)>;
53275328
def : Pat<(int_ppc_stwcx ForceXForm:$dst, gprc:$A),
53285329
(RLWINM (STWCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
53295330
def : Pat<(PPCStoreCond ForceXForm:$dst, gprc:$A, 4),
53305331
(RLWINM (STWCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5332+
def : Pat<(int_ppc_lbarx ForceXForm:$ptr),
5333+
(LBARX ForceXForm:$ptr)>;
53315334
def : Pat<(int_ppc_stbcx ForceXForm:$dst, gprc:$A),
53325335
(RLWINM (STBCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
53335336
def : Pat<(PPCStoreCond ForceXForm:$dst, gprc:$A, 1),
@@ -5360,6 +5363,9 @@ def : Pat<(int_ppc_mtmsr gprc:$RS),
53605363
(MTMSR $RS, 0)>;
53615364

53625365
let Predicates = [IsISA2_07] in {
5366+
def : Pat<(int_ppc_lharx ForceXForm:$ptr),
5367+
(LHARX ForceXForm:$ptr)>;
5368+
53635369
def : Pat<(int_ppc_sthcx ForceXForm:$dst, gprc:$A),
53645370
(RLWINM (STHCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
53655371
def : Pat<(PPCStoreCond ForceXForm:$dst, gprc:$A, 2),

0 commit comments

Comments
 (0)