llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Maryam Moghadas (maryammo) <details> <summary>Changes</summary> 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 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 *ptr, int32_t val) { + __builtin_amo_stwat_s(ptr, val, _AMO_ST_SMIN); +} + +/* 64-bit unsigned AMO store operations */ +static inline void amo_stdat_add(uint64_t *ptr, uint64_t val) { + __builtin_amo_stdat(ptr, val, _AMO_ST_ADD); +} + +static inline void amo_stdat_xor(uint64_t *ptr, uint64_t val) { + __builtin_amo_stdat(ptr, val, _AMO_ST_XOR); +} + +static inline void amo_stdat_ior(uint64_t *ptr, uint64_t val) { + __builtin_amo_stdat(ptr, val, _AMO_ST_IOR); +} + +static inline void amo_stdat_and(uint64_t *ptr, uint64_t val) { + __builtin_amo_stdat(ptr, val, _AMO_ST_AND); +} + +static inline void amo_stdat_umax(uint64_t *ptr, uint64_t val) { + __builtin_amo_stdat(ptr, val, _AMO_ST_UMAX); +} + +static inline void amo_stdat_umin(uint64_t *ptr, uint64_t val) { + __builtin_amo_stdat(ptr, val, _AMO_ST_UMIN); +} + +/* 64-bit signed AMO store operations */ +static inline void amo_stdat_sadd(int64_t *ptr, int64_t val) { + __builtin_amo_stdat_s(ptr, val, _AMO_ST_ADD); +} + +static inline void amo_stdat_smax(int64_t *ptr, int64_t val) { + __builtin_amo_stdat_s(ptr, val, _AMO_ST_SMAX); +} + +static inline void amo_stdat_smin(int64_t *ptr, int64_t val) { + __builtin_amo_stdat_s(ptr, val, _AMO_ST_SMIN); +} + #ifdef __cplusplus } #endif diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp index a7e76a9917372..1bf806d996887 100644 --- a/clang/lib/Sema/SemaPPC.cpp +++ b/clang/lib/Sema/SemaPPC.cpp @@ -95,6 +95,10 @@ static bool isPPC_64Builtin(unsigned BuiltinID) { case PPC::BI__builtin_amo_ldat_cond: case PPC::BI__builtin_amo_lwat_cond_s: case PPC::BI__builtin_amo_ldat_cond_s: + case PPC::BI__builtin_amo_stwat: + case PPC::BI__builtin_amo_stdat: + case PPC::BI__builtin_amo_stwat_s: + case PPC::BI__builtin_amo_stdat_s: return true; } return false; @@ -300,6 +304,30 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI, return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range) << toString(Result, 10) << "24, 25" << "28" << Arg->getSourceRange(); } + case PPC::BI__builtin_amo_stwat: + case PPC::BI__builtin_amo_stdat: + case PPC::BI__builtin_amo_stwat_s: + case PPC::BI__builtin_amo_stdat_s: { + llvm::APSInt Result; + if (SemaRef.BuiltinConstantArg(TheCall, 2, Result)) + return true; + unsigned Val = Result.getZExtValue(); + + bool IsUnsigned = (BuiltinID == PPC::BI__builtin_amo_stwat || + BuiltinID == PPC::BI__builtin_amo_stdat); + + bool IsValid = IsUnsigned + ? llvm::is_contained({0u, 1u, 2u, 3u, 4u, 6u, 24u}, Val) + : llvm::is_contained({0u, 5u, 7u, 24u}, Val); + + if (IsValid) + return false; + + Expr *Arg = TheCall->getArg(2); + return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range) + << toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7") + << "24" << Arg->getSourceRange(); + } } llvm_unreachable("must return from switch"); } diff --git a/clang/test/CodeGen/PowerPC/builtins-amo-err.c b/clang/test/CodeGen/PowerPC/builtins-amo-err.c index ad6be9e867856..f99efd0505818 100644 --- a/clang/test/CodeGen/PowerPC/builtins-amo-err.c +++ b/clang/test/CodeGen/PowerPC/builtins-amo-err.c @@ -51,4 +51,28 @@ void test_amo() { __builtin_amo_ldat_cond_s(ptr6, 28); // FC-ERROR: argument value 0 is outside the valid range [24, 25, 28] __builtin_amo_ldat_cond_s(ptr6, 0); + + unsigned int *ptr9, value9; + // AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets + __builtin_amo_stwat(ptr9, value9, 0); + // FC-ERROR: error: argument value 5 is outside the valid range [0-4, 6, 24] + __builtin_amo_stwat(ptr9, value9, 5); + + unsigned long int *ptr10, value10; + // AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets + __builtin_amo_stdat(ptr10, value10, 24); + // FC-ERROR: error: argument value 10 is outside the valid range [0-4, 6, 24] + __builtin_amo_stdat(ptr10, value10, 10); + + signed int *ptr11, value11; + // AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets + __builtin_amo_stwat_s(ptr11, value11, 0); + // FC-ERROR: error: argument value 1 is outside the valid range [0, 5, 7, 24] + __builtin_amo_stwat_s(ptr11, value11, 1); + + signed long int *ptr12, value12; + // AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets + __builtin_amo_stdat_s(ptr12, value12, 24); + // FC-ERROR: error: argument value 6 is outside the valid range [0, 5, 7, 24] + __builtin_amo_stdat_s(ptr12, value12, 6); } diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c b/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c index 0bf28e85730e1..ffbedd8c50202 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c @@ -156,6 +156,69 @@ void test_signed_ldat_cond(long int *ptr, long int * resp) { *resp = res; } +// CHECK-LABEL: define dso_local void @test_unsigned_stwat( +// CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef zeroext [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.ppc.amo.stwat(ptr [[PTR]], i32 [[VALUE]], i32 24) +// CHECK-NEXT: ret void +// +// AIX-LABEL: define void @test_unsigned_stwat( +// AIX-SAME: ptr noundef [[PTR:%.*]], i32 noundef zeroext [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AIX-NEXT: [[ENTRY:.*:]] +// AIX-NEXT: tail call void @llvm.ppc.amo.stwat(ptr [[PTR]], i32 [[VALUE]], i32 24) +// AIX-NEXT: ret void +// +void test_unsigned_stwat(unsigned int *ptr, unsigned int value, unsigned int * resp) { + __builtin_amo_stwat(ptr, value, 24); +} + +// CHECK-LABEL: define dso_local void @test_unsigned_stdat( +// CHECK-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.ppc.amo.stdat(ptr [[PTR]], i64 [[VALUE]], i32 3) +// CHECK-NEXT: ret void +// +// AIX-LABEL: define void @test_unsigned_stdat( +// AIX-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AIX-NEXT: [[ENTRY:.*:]] +// AIX-NEXT: tail call void @llvm.ppc.amo.stdat(ptr [[PTR]], i64 [[VALUE]], i32 3) +// AIX-NEXT: ret void +// +void test_unsigned_stdat(unsigned long int *ptr, unsigned long int value, unsigned long int * resp) { + __builtin_amo_stdat(ptr, value, 3); +} + +// CHECK-LABEL: define dso_local void @test_signed_stwat( +// CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef signext [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.ppc.amo.stwat(ptr [[PTR]], i32 [[VALUE]], i32 24) +// CHECK-NEXT: ret void +// +// AIX-LABEL: define void @test_signed_stwat( +// AIX-SAME: ptr noundef [[PTR:%.*]], i32 noundef signext [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AIX-NEXT: [[ENTRY:.*:]] +// AIX-NEXT: tail call void @llvm.ppc.amo.stwat(ptr [[PTR]], i32 [[VALUE]], i32 24) +// AIX-NEXT: ret void +// +void test_signed_stwat(int *ptr, int value, int * resp) { + __builtin_amo_stwat_s(ptr, value, 24); +} + +// CHECK-LABEL: define dso_local void @test_signed_stdat( +// CHECK-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.ppc.amo.stdat(ptr [[PTR]], i64 [[VALUE]], i32 5) +// CHECK-NEXT: ret void +// +// AIX-LABEL: define void @test_signed_stdat( +// AIX-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef readnone captures(none) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AIX-NEXT: [[ENTRY:.*:]] +// AIX-NEXT: tail call void @llvm.ppc.amo.stdat(ptr [[PTR]], i64 [[VALUE]], i32 5) +// AIX-NEXT: ret void +// +void test_signed_stdat(long int *ptr, long int value, long int * resp) { + __builtin_amo_stdat_s(ptr, value, 5); +} //. // CHECK: [[INT_TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} // CHECK: [[META3]] = !{!"int", [[META4:![0-9]+]], i64 0} diff --git a/clang/test/CodeGen/PowerPC/ppc-amo-header.c b/clang/test/CodeGen/PowerPC/ppc-amo-header.c index ffc87561fa3c4..e0acbf2dd8fa2 100644 --- a/clang/test/CodeGen/PowerPC/ppc-amo-header.c +++ b/clang/test/CodeGen/PowerPC/ppc-amo-header.c @@ -137,3 +137,111 @@ int64_t test_ldat_sswap(int64_t *ptr, int64_t val) { // CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 8) return amo_ldat_sswap(ptr, val); } + +void test_stwat_add(uint32_t *ptr, uint32_t val) { + // CHECK-LABEL: @test_stwat_add + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 0) + return amo_stwat_add(ptr, val); +} + +void test_stwat_xor(uint32_t *ptr, uint32_t val) { + // CHECK-LABEL: @test_stwat_xor + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 1) + return amo_stwat_xor(ptr, val); +} + +void test_stwat_ior(uint32_t *ptr, uint32_t val) { + // CHECK-LABEL: @test_stwat_ior + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 2) + return amo_stwat_ior(ptr, val); +} + +void test_stwat_and(uint32_t *ptr, uint32_t val) { + // CHECK-LABEL: @test_stwat_and + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 3) + return amo_stwat_and(ptr, val); +} + +void test_stwat_umax(uint32_t *ptr, uint32_t val) { + // CHECK-LABEL: @test_stwat_umax + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 4) + return amo_stwat_umax(ptr, val); +} + +void test_stwat_umin(uint32_t *ptr, uint32_t val) { + // CHECK-LABEL: @test_stwat_umin + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 6) + return amo_stwat_umin(ptr, val); +} + +void test_stwat_sadd(int32_t *ptr, int32_t val) { + // CHECK-LABEL: @test_stwat_sadd + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 0) + return amo_stwat_sadd(ptr, val); +} + +void test_stwat_smax(int32_t *ptr, int32_t val) { + // CHECK-LABEL: @test_stwat_smax + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 5) + return amo_stwat_smax(ptr, val); +} + +void test_stwat_smin(int32_t *ptr, int32_t val) { + // CHECK-LABEL: @test_stwat_smin + // CHECK: call void @llvm.ppc.amo.stwat(ptr %{{.*}}, i32 %{{.*}}, i32 7) + return amo_stwat_smin(ptr, val); +} + +void test_stdat_add(uint64_t *ptr, uint64_t val) { + // CHECK-LABEL: @test_stdat_add + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 0) + return amo_stdat_add(ptr, val); +} + +void test_stdat_xor(uint64_t *ptr, uint64_t val) { + // CHECK-LABEL: @test_stdat_xor + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 1) + return amo_stdat_xor(ptr, val); +} + +void test_stdat_ior(uint64_t *ptr, uint64_t val) { + // CHECK-LABEL: @test_stdat_ior + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 2) + return amo_stdat_ior(ptr, val); +} + +void test_stdat_and(uint64_t *ptr, uint64_t val) { + // CHECK-LABEL: @test_stdat_and + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 3) + return amo_stdat_and(ptr, val); +} + +void test_stdat_umax(uint64_t *ptr, uint64_t val) { + // CHECK-LABEL: @test_stdat_umax + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 4) + return amo_stdat_umax(ptr, val); +} + +void test_stdat_umin(uint64_t *ptr, uint64_t val) { + // CHECK-LABEL: @test_stdat_umin + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 6) + return amo_stdat_umin(ptr, val); +} + +void test_stdat_sadd(int64_t *ptr, int64_t val) { + // CHECK-LABEL: @test_stdat_sadd + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 0) + return amo_stdat_sadd(ptr, val); +} + +void test_stdat_smax(int64_t *ptr, int64_t val) { + // CHECK-LABEL: @test_stdat_smax + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 5) + return amo_stdat_smax(ptr, val); +} + +void test_stdat_smin(int64_t *ptr, int64_t val) { + // CHECK-LABEL: @test_stdat_smin + // CHECK: call void @llvm.ppc.amo.stdat(ptr %{{.*}}, i64 %{{.*}}, i32 7) + return amo_stdat_smin(ptr, val); +} diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index e13f40454fba2..ce27e9163560b 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -2158,4 +2158,13 @@ let TargetPrefix = "ppc" in { DefaultAttrsIntrinsic<[llvm_i64_ty],[llvm_ptr_ty, llvm_i32_ty], [IntrArgMemOnly, ImmArg<ArgIndex<1>>]>; + + def int_ppc_amo_stwat : ClangBuiltin<"__builtin_amo_stwat">, + DefaultAttrsIntrinsic<[],[llvm_ptr_ty, + llvm_i32_ty, llvm_i32_ty], + [IntrArgMemOnly, ImmArg<ArgIndex<2>>]>; + def int_ppc_amo_stdat : ClangBuiltin<"__builtin_amo_stdat">, + DefaultAttrsIntrinsic<[],[llvm_ptr_ty, + llvm_i64_ty, llvm_i32_ty], + [IntrArgMemOnly, ImmArg<ArgIndex<2>>]>; } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 2ddd991f5e997..bcb7d5cceb0f0 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -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<ConstantSDNode>(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}); + return SDValue(MNode, 0); + } default: break; } diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td index 9fa284716dc71..45614923d9477 100644 --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -412,7 +412,7 @@ def : Pat<(int_ppc_cmpxchg_i128 ForceXForm:$ptr, g8rc:$new_hi))>; let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in -def STDAT : X_RD5_RS5_IM5<31, 742, (outs), (ins g8rc:$RST, g8rc:$RA, u5imm:$RB), +def STDAT : X_RD5_RS5_IM5<31, 742, (outs), (ins g8rc:$RST, ptr_rc_nor0:$RA, u5imm:$RB), "stdat $RST, $RA, $RB", IIC_LdStStore>, isPPC64, Requires<[IsISA3_0]>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 67bbed63bfc13..b7b687fe197a1 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -2157,7 +2157,7 @@ def STWCX : XForm_1_memOp<31, 150, (outs), (ins gprc:$RST, (memrr $RA, $RB):$add } let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in -def STWAT : X_RD5_RS5_IM5<31, 710, (outs), (ins gprc:$RST, gprc:$RA, u5imm:$RB), +def STWAT : X_RD5_RS5_IM5<31, 710, (outs), (ins gprc:$RST, ptr_rc_nor0:$RA, u5imm:$RB), "stwat $RST, $RA, $RB", IIC_LdStStore>, Requires<[IsISA3_0]>; diff --git a/llvm/test/CodeGen/PowerPC/amo-enable.ll b/llvm/test/CodeGen/PowerPC/amo-enable.ll index 4e80d95b38e3f..760952a9a4c4c 100644 --- a/llvm/test/CodeGen/PowerPC/amo-e... [truncated] `````````` </details> 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
