[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
https://github.com/RolandF77 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/170933 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
https://github.com/maryammo updated
https://github.com/llvm/llvm-project/pull/170933
>From eec7926a03e86c6670fadd9d342cf073b64fd81a Mon Sep 17 00:00:00 2001
From: Maryam Moghadas
Date: Wed, 3 Dec 2025 22:59:57 +
Subject: [PATCH 1/3] [PowerPC] Add support for AMO store builtins
---
clang/include/clang/Basic/BuiltinsPPC.def | 5 +
clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 14 +++
clang/lib/Headers/amo.h | 89 +++
clang/lib/Sema/SemaPPC.cpp| 28 +
clang/test/CodeGen/PowerPC/builtins-amo-err.c | 24
clang/test/CodeGen/PowerPC/builtins-ppc-amo.c | 63 ++
clang/test/CodeGen/PowerPC/ppc-amo-header.c | 108 ++
llvm/include/llvm/IR/IntrinsicsPowerPC.td | 9 ++
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 24
llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 2 +-
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 2 +-
llvm/test/CodeGen/PowerPC/amo-enable.ll | 32 ++
12 files changed, 398 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def
b/clang/include/clang/Basic/BuiltinsPPC.def
index 7689daf00e6a7..f518429136e3c 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1010,6 +1010,11 @@ TARGET_BUILTIN(__builtin_amo_lwat_cond, "UiUi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond, "ULiULi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_lwat_cond_s, "SiSi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond_s, "SLiSLi*Ii", "",
"isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat, "vUi*UiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat, "vULi*ULiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat_s, "vSi*SiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat_s, "vSLi*SLiIi", "", "isa-v30-instructions")
+
// Set the floating point rounding mode
BUILTIN(__builtin_setrnd, "di", "")
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index bccb6acdb4e06..6568959351a5d 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1386,5 +1386,19 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned
BuiltinID,
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
{Op0, Op1});
}
+ case PPC::BI__builtin_amo_stwat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stwat),
+ {Op0, Op1, Op2});
+ }
+ case PPC::BI__builtin_amo_stdat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stdat),
+ {Op0, Op1, Op2});
+ }
}
}
diff --git a/clang/lib/Headers/amo.h b/clang/lib/Headers/amo.h
index 97eff35e9c5dc..c7563f203d1f8 100644
--- a/clang/lib/Headers/amo.h
+++ b/clang/lib/Headers/amo.h
@@ -124,6 +124,95 @@ static inline int64_t amo_ldat_sswap(int64_t *ptr, int64_t
val) {
return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SWAP);
}
+/* AMO Store Operation Codes (FC values) */
+enum _AMO_ST {
+ _AMO_ST_ADD = 0x00, /* Store Add */
+ _AMO_ST_XOR = 0x01, /* Store Xor */
+ _AMO_ST_IOR = 0x02, /* Store Ior */
+ _AMO_ST_AND = 0x03, /* Store And */
+ _AMO_ST_UMAX = 0x04, /* Store Unsigned Maximum */
+ _AMO_ST_SMAX = 0x05, /* Store Signed Maximum */
+ _AMO_ST_UMIN = 0x06, /* Store Unsigned Minimum */
+ _AMO_ST_SMIN = 0x07, /* Store Signed Minimum */
+ _AMO_ST_TWIN = 0x18 /* Store Twin */
+};
+
+/* 32-bit unsigned AMO store operations */
+static inline void amo_stwat_add(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_ADD);
+}
+
+static inline void amo_stwat_xor(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_XOR);
+}
+
+static inline void amo_stwat_ior(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_IOR);
+}
+
+static inline void amo_stwat_and(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_AND);
+}
+
+static inline void amo_stwat_umax(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMAX);
+}
+
+static inline void amo_stwat_umin(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMIN);
+}
+
+/* 32-bit signed AMO store operations */
+static inline void amo_stwat_sadd(int32_t *ptr, int32_t val) {
+ __builtin_amo_stwat_s(ptr, val, _AMO_ST_ADD);
+}
+
+static inline void amo_stwat_smax(int32_t *ptr, int32_t val) {
+ __builtin_amo_stwat_s(ptr, val, _AMO_ST_SMAX);
+}
+
+static inline void amo_stwat_smin(int32_t
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -5604,3 +5611,6 @@ def : Pat<(int_ppc_dcbtt ForceXForm:$dst), def : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT), (STFIWX f64:$XT, ForceXForm:$dst)>; + +def : Pat<(PPCstat i32:$val, ptr_rc_nor0:$ptr, timm:$fc), + (STWAT $val, $ptr, $fc)>; RolandF77 wrote: Can you just use the underlying class XForm_base_r3xo_memOp? It kind of looks like the only purpose of the X_RD5_RS5_IM5 class it to use the other class but prevent patterns. Maybe that makes sense for the loads, which are pretty weird, but for stores patterns may be okay. https://github.com/llvm/llvm-project/pull/170933 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -5604,3 +5611,6 @@ def : Pat<(int_ppc_dcbtt ForceXForm:$dst), def : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT), (STFIWX f64:$XT, ForceXForm:$dst)>; + +def : Pat<(PPCstat i32:$val, ptr_rc_nor0:$ptr, timm:$fc), + (STWAT $val, $ptr, $fc)>; maryammo wrote: STWAT/STDAT are defined using X_RD5_RS5_IM5 class which does not accept SDAG pattern for matching. https://github.com/llvm/llvm-project/pull/170933 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -5604,3 +5611,6 @@ def : Pat<(int_ppc_dcbtt ForceXForm:$dst), def : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT), (STFIWX f64:$XT, ForceXForm:$dst)>; + +def : Pat<(PPCstat i32:$val, ptr_rc_nor0:$ptr, timm:$fc), + (STWAT $val, $ptr, $fc)>; RolandF77 wrote: Is there some reason the pattern can't go directly in the def STWAT, like with frsqrte? https://github.com/llvm/llvm-project/pull/170933 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -2007,3 +2007,5 @@ def : Pat<(i64 (int_ppc_mfspr timm:$SPR)), (MFSPR8 $SPR)>; def : Pat<(int_ppc_mtspr timm:$SPR, g8rc:$RT), (MTSPR8 $SPR, $RT)>; +def : Pat<(PPCstat i64:$val, ptr_rc_nor0:$ptr, timm:$fc), + (STDAT $val, $ptr, $fc)>; RolandF77 wrote: Same as with STWAT, can this go in the def STDAT? https://github.com/llvm/llvm-project/pull/170933 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
https://github.com/maryammo updated
https://github.com/llvm/llvm-project/pull/170933
>From eec7926a03e86c6670fadd9d342cf073b64fd81a Mon Sep 17 00:00:00 2001
From: Maryam Moghadas
Date: Wed, 3 Dec 2025 22:59:57 +
Subject: [PATCH] [PowerPC] Add support for AMO store builtins
---
clang/include/clang/Basic/BuiltinsPPC.def | 5 +
clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 14 +++
clang/lib/Headers/amo.h | 89 +++
clang/lib/Sema/SemaPPC.cpp| 28 +
clang/test/CodeGen/PowerPC/builtins-amo-err.c | 24
clang/test/CodeGen/PowerPC/builtins-ppc-amo.c | 63 ++
clang/test/CodeGen/PowerPC/ppc-amo-header.c | 108 ++
llvm/include/llvm/IR/IntrinsicsPowerPC.td | 9 ++
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 24
llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 2 +-
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 2 +-
llvm/test/CodeGen/PowerPC/amo-enable.ll | 32 ++
12 files changed, 398 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def
b/clang/include/clang/Basic/BuiltinsPPC.def
index 7689daf00e6a7..f518429136e3c 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1010,6 +1010,11 @@ TARGET_BUILTIN(__builtin_amo_lwat_cond, "UiUi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond, "ULiULi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_lwat_cond_s, "SiSi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond_s, "SLiSLi*Ii", "",
"isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat, "vUi*UiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat, "vULi*ULiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat_s, "vSi*SiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat_s, "vSLi*SLiIi", "", "isa-v30-instructions")
+
// Set the floating point rounding mode
BUILTIN(__builtin_setrnd, "di", "")
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index bccb6acdb4e06..6568959351a5d 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1386,5 +1386,19 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned
BuiltinID,
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
{Op0, Op1});
}
+ case PPC::BI__builtin_amo_stwat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stwat),
+ {Op0, Op1, Op2});
+ }
+ case PPC::BI__builtin_amo_stdat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stdat),
+ {Op0, Op1, Op2});
+ }
}
}
diff --git a/clang/lib/Headers/amo.h b/clang/lib/Headers/amo.h
index 97eff35e9c5dc..c7563f203d1f8 100644
--- a/clang/lib/Headers/amo.h
+++ b/clang/lib/Headers/amo.h
@@ -124,6 +124,95 @@ static inline int64_t amo_ldat_sswap(int64_t *ptr, int64_t
val) {
return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SWAP);
}
+/* AMO Store Operation Codes (FC values) */
+enum _AMO_ST {
+ _AMO_ST_ADD = 0x00, /* Store Add */
+ _AMO_ST_XOR = 0x01, /* Store Xor */
+ _AMO_ST_IOR = 0x02, /* Store Ior */
+ _AMO_ST_AND = 0x03, /* Store And */
+ _AMO_ST_UMAX = 0x04, /* Store Unsigned Maximum */
+ _AMO_ST_SMAX = 0x05, /* Store Signed Maximum */
+ _AMO_ST_UMIN = 0x06, /* Store Unsigned Minimum */
+ _AMO_ST_SMIN = 0x07, /* Store Signed Minimum */
+ _AMO_ST_TWIN = 0x18 /* Store Twin */
+};
+
+/* 32-bit unsigned AMO store operations */
+static inline void amo_stwat_add(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_ADD);
+}
+
+static inline void amo_stwat_xor(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_XOR);
+}
+
+static inline void amo_stwat_ior(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_IOR);
+}
+
+static inline void amo_stwat_and(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_AND);
+}
+
+static inline void amo_stwat_umax(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMAX);
+}
+
+static inline void amo_stwat_umin(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMIN);
+}
+
+/* 32-bit signed AMO store operations */
+static inline void amo_stwat_sadd(int32_t *ptr, int32_t val) {
+ __builtin_amo_stwat_s(ptr, val, _AMO_ST_ADD);
+}
+
+static inline void amo_stwat_smax(int32_t *ptr, int32_t val) {
+ __builtin_amo_stwat_s(ptr, val, _AMO_ST_SMAX);
+}
+
+static inline void amo_stwat_smin(int32_t *pt
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
https://github.com/maryammo edited https://github.com/llvm/llvm-project/pull/170933 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -11482,6 +11482,30 @@ SDValue PPCTargetLowering::LowerINTRINSIC_VOID(SDValue
Op,
return DAG.getStore(DAG.getEntryNode(), DL, Op.getOperand(ArgStart + 2),
Op.getOperand(ArgStart + 1), MachinePointerInfo());
}
+ case Intrinsic::ppc_amo_stwat:
+ case Intrinsic::ppc_amo_stdat: {
+SDLoc dl(Op);
+SDValue Chain = Op.getOperand(0);
+SDValue Ptr = Op.getOperand(ArgStart + 1);
+SDValue Val = Op.getOperand(ArgStart + 2);
+SDValue FC = Op.getOperand(ArgStart + 3);
+
+bool IsStwat =
+Op.getConstantOperandVal(ArgStart) == Intrinsic::ppc_amo_stwat;
+if (isa(Val)) {
+ MVT VT = IsStwat ? MVT::i32 : MVT::i64;
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ Register ValReg = MRI.createVirtualRegister(getRegClassFor(VT));
+
+ // Materialize constant Val using CopyToReg/CopyFromReg.
+ SDValue CopyChain = DAG.getCopyToReg(Chain, dl, ValReg, Val);
+ Val = DAG.getCopyFromReg(CopyChain, dl, ValReg, VT);
+}
maryammo wrote:
Using getMachineNode bypasses materializes constants. This;
CopyToReg/CopyFromReg; manually forces constants into registers before the
machine instruction.
https://github.com/llvm/llvm-project/pull/170933
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -11482,6 +11482,30 @@ SDValue PPCTargetLowering::LowerINTRINSIC_VOID(SDValue
Op,
return DAG.getStore(DAG.getEntryNode(), DL, Op.getOperand(ArgStart + 2),
Op.getOperand(ArgStart + 1), MachinePointerInfo());
}
+ case Intrinsic::ppc_amo_stwat:
+ case Intrinsic::ppc_amo_stdat: {
+SDLoc dl(Op);
+SDValue Chain = Op.getOperand(0);
+SDValue Ptr = Op.getOperand(ArgStart + 1);
+SDValue Val = Op.getOperand(ArgStart + 2);
+SDValue FC = Op.getOperand(ArgStart + 3);
+
+bool IsStwat =
+Op.getConstantOperandVal(ArgStart) == Intrinsic::ppc_amo_stwat;
+if (isa(Val)) {
+ MVT VT = IsStwat ? MVT::i32 : MVT::i64;
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ Register ValReg = MRI.createVirtualRegister(getRegClassFor(VT));
+
+ // Materialize constant Val using CopyToReg/CopyFromReg.
+ SDValue CopyChain = DAG.getCopyToReg(Chain, dl, ValReg, Val);
+ Val = DAG.getCopyFromReg(CopyChain, dl, ValReg, VT);
+}
+MachineSDNode *MNode = DAG.getMachineNode(IsStwat ? PPC::STWAT :
PPC::STDAT,
+ dl, MVT::Other, {Val, Ptr, FC});
RolandF77 wrote:
As with lwat/ldat, I think we should try to avoid using a machine node if we
can.
https://github.com/llvm/llvm-project/pull/170933
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
@@ -11482,6 +11482,30 @@ SDValue PPCTargetLowering::LowerINTRINSIC_VOID(SDValue
Op,
return DAG.getStore(DAG.getEntryNode(), DL, Op.getOperand(ArgStart + 2),
Op.getOperand(ArgStart + 1), MachinePointerInfo());
}
+ case Intrinsic::ppc_amo_stwat:
+ case Intrinsic::ppc_amo_stdat: {
+SDLoc dl(Op);
+SDValue Chain = Op.getOperand(0);
+SDValue Ptr = Op.getOperand(ArgStart + 1);
+SDValue Val = Op.getOperand(ArgStart + 2);
+SDValue FC = Op.getOperand(ArgStart + 3);
+
+bool IsStwat =
+Op.getConstantOperandVal(ArgStart) == Intrinsic::ppc_amo_stwat;
+if (isa(Val)) {
+ MVT VT = IsStwat ? MVT::i32 : MVT::i64;
+ MachineFunction &MF = DAG.getMachineFunction();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ Register ValReg = MRI.createVirtualRegister(getRegClassFor(VT));
+
+ // Materialize constant Val using CopyToReg/CopyFromReg.
+ SDValue CopyChain = DAG.getCopyToReg(Chain, dl, ValReg, Val);
+ Val = DAG.getCopyFromReg(CopyChain, dl, ValReg, VT);
+}
RolandF77 wrote:
I haven't ever seen code like this. Constants are usually handled without extra
code. Is this because of using a machine node?
https://github.com/llvm/llvm-project/pull/170933
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Maryam Moghadas (maryammo)
Changes
This commit adds 4 Clang builtins for PowerPC AMO store operations:
__builtin_amo_stwat for 32-bit unsigned operations
__builtin_amo_stdat for 64-bit unsigned operations
__builtin_amo_stwat_s for 32-bit signed operations
__builtin_amo_stdat_s for 64-bit signed operations
and maps GCC's AMO store functions to these Clang builtins for compatibility.
---
Patch is 21.21 KiB, truncated to 20.00 KiB below, full version:
https://github.com/llvm/llvm-project/pull/170933.diff
12 Files Affected:
- (modified) clang/include/clang/Basic/BuiltinsPPC.def (+5)
- (modified) clang/lib/CodeGen/TargetBuiltins/PPC.cpp (+14)
- (modified) clang/lib/Headers/amo.h (+89)
- (modified) clang/lib/Sema/SemaPPC.cpp (+28)
- (modified) clang/test/CodeGen/PowerPC/builtins-amo-err.c (+24)
- (modified) clang/test/CodeGen/PowerPC/builtins-ppc-amo.c (+63)
- (modified) clang/test/CodeGen/PowerPC/ppc-amo-header.c (+108)
- (modified) llvm/include/llvm/IR/IntrinsicsPowerPC.td (+9)
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+24)
- (modified) llvm/lib/Target/PowerPC/PPCInstr64Bit.td (+1-1)
- (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.td (+1-1)
- (modified) llvm/test/CodeGen/PowerPC/amo-enable.ll (+32)
``diff
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def
b/clang/include/clang/Basic/BuiltinsPPC.def
index 7689daf00e6a7..f518429136e3c 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1010,6 +1010,11 @@ TARGET_BUILTIN(__builtin_amo_lwat_cond, "UiUi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond, "ULiULi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_lwat_cond_s, "SiSi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond_s, "SLiSLi*Ii", "",
"isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat, "vUi*UiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat, "vULi*ULiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat_s, "vSi*SiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat_s, "vSLi*SLiIi", "", "isa-v30-instructions")
+
// Set the floating point rounding mode
BUILTIN(__builtin_setrnd, "di", "")
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index bccb6acdb4e06..6568959351a5d 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1386,5 +1386,19 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned
BuiltinID,
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
{Op0, Op1});
}
+ case PPC::BI__builtin_amo_stwat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stwat),
+ {Op0, Op1, Op2});
+ }
+ case PPC::BI__builtin_amo_stdat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stdat),
+ {Op0, Op1, Op2});
+ }
}
}
diff --git a/clang/lib/Headers/amo.h b/clang/lib/Headers/amo.h
index 97eff35e9c5dc..c7563f203d1f8 100644
--- a/clang/lib/Headers/amo.h
+++ b/clang/lib/Headers/amo.h
@@ -124,6 +124,95 @@ static inline int64_t amo_ldat_sswap(int64_t *ptr, int64_t
val) {
return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SWAP);
}
+/* AMO Store Operation Codes (FC values) */
+enum _AMO_ST {
+ _AMO_ST_ADD = 0x00, /* Store Add */
+ _AMO_ST_XOR = 0x01, /* Store Xor */
+ _AMO_ST_IOR = 0x02, /* Store Ior */
+ _AMO_ST_AND = 0x03, /* Store And */
+ _AMO_ST_UMAX = 0x04, /* Store Unsigned Maximum */
+ _AMO_ST_SMAX = 0x05, /* Store Signed Maximum */
+ _AMO_ST_UMIN = 0x06, /* Store Unsigned Minimum */
+ _AMO_ST_SMIN = 0x07, /* Store Signed Minimum */
+ _AMO_ST_TWIN = 0x18 /* Store Twin */
+};
+
+/* 32-bit unsigned AMO store operations */
+static inline void amo_stwat_add(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_ADD);
+}
+
+static inline void amo_stwat_xor(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_XOR);
+}
+
+static inline void amo_stwat_ior(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_IOR);
+}
+
+static inline void amo_stwat_and(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_AND);
+}
+
+static inline void amo_stwat_umax(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMAX);
+}
+
+static inline void amo_stwat_umin(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMIN);
+}
+
+/* 32-bit signed AMO store operations */
+static inline v
[llvm-branch-commits] [clang] [llvm] [PowerPC] Add support for AMO store builtins (PR #170933)
https://github.com/maryammo created
https://github.com/llvm/llvm-project/pull/170933
This commit adds 4 Clang builtins for PowerPC AMO store operations:
__builtin_amo_stwat for 32-bit unsigned operations
__builtin_amo_stdat for 64-bit unsigned operations
__builtin_amo_stwat_s for 32-bit signed operations
__builtin_amo_stdat_s for 64-bit signed operations
and maps GCC's AMO store functions to these Clang builtins for compatibility.
>From aa5e8c5224fdf8c42bccbe331e7dfcb096a67606 Mon Sep 17 00:00:00 2001
From: Maryam Moghadas
Date: Wed, 3 Dec 2025 22:59:57 +
Subject: [PATCH] [PowerPC] Add support for AMO store builtins
---
clang/include/clang/Basic/BuiltinsPPC.def | 5 +
clang/lib/CodeGen/TargetBuiltins/PPC.cpp | 14 +++
clang/lib/Headers/amo.h | 89 +++
clang/lib/Sema/SemaPPC.cpp| 28 +
clang/test/CodeGen/PowerPC/builtins-amo-err.c | 24
clang/test/CodeGen/PowerPC/builtins-ppc-amo.c | 63 ++
clang/test/CodeGen/PowerPC/ppc-amo-header.c | 108 ++
llvm/include/llvm/IR/IntrinsicsPowerPC.td | 9 ++
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 24
llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 2 +-
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 2 +-
llvm/test/CodeGen/PowerPC/amo-enable.ll | 32 ++
12 files changed, 398 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def
b/clang/include/clang/Basic/BuiltinsPPC.def
index 7689daf00e6a7..f518429136e3c 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1010,6 +1010,11 @@ TARGET_BUILTIN(__builtin_amo_lwat_cond, "UiUi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond, "ULiULi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_lwat_cond_s, "SiSi*Ii", "",
"isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat_cond_s, "SLiSLi*Ii", "",
"isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat, "vUi*UiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat, "vULi*ULiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stwat_s, "vSi*SiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_stdat_s, "vSLi*SLiIi", "", "isa-v30-instructions")
+
// Set the floating point rounding mode
BUILTIN(__builtin_setrnd, "di", "")
diff --git a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
index bccb6acdb4e06..6568959351a5d 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1386,5 +1386,19 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned
BuiltinID,
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
{Op0, Op1});
}
+ case PPC::BI__builtin_amo_stwat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stwat),
+ {Op0, Op1, Op2});
+ }
+ case PPC::BI__builtin_amo_stdat_s: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Op2 = EmitScalarExpr(E->getArg(2));
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_stdat),
+ {Op0, Op1, Op2});
+ }
}
}
diff --git a/clang/lib/Headers/amo.h b/clang/lib/Headers/amo.h
index 97eff35e9c5dc..c7563f203d1f8 100644
--- a/clang/lib/Headers/amo.h
+++ b/clang/lib/Headers/amo.h
@@ -124,6 +124,95 @@ static inline int64_t amo_ldat_sswap(int64_t *ptr, int64_t
val) {
return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SWAP);
}
+/* AMO Store Operation Codes (FC values) */
+enum _AMO_ST {
+ _AMO_ST_ADD = 0x00, /* Store Add */
+ _AMO_ST_XOR = 0x01, /* Store Xor */
+ _AMO_ST_IOR = 0x02, /* Store Ior */
+ _AMO_ST_AND = 0x03, /* Store And */
+ _AMO_ST_UMAX = 0x04, /* Store Unsigned Maximum */
+ _AMO_ST_SMAX = 0x05, /* Store Signed Maximum */
+ _AMO_ST_UMIN = 0x06, /* Store Unsigned Minimum */
+ _AMO_ST_SMIN = 0x07, /* Store Signed Minimum */
+ _AMO_ST_TWIN = 0x18 /* Store Twin */
+};
+
+/* 32-bit unsigned AMO store operations */
+static inline void amo_stwat_add(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_ADD);
+}
+
+static inline void amo_stwat_xor(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_XOR);
+}
+
+static inline void amo_stwat_ior(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_IOR);
+}
+
+static inline void amo_stwat_and(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_AND);
+}
+
+static inline void amo_stwat_umax(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(ptr, val, _AMO_ST_UMAX);
+}
+
+static inline void amo_stwat_umin(uint32_t *ptr, uint32_t val) {
+ __builtin_amo_stwat(pt
