-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[PowerPC] Add AMO load signed builtins #168747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/maryammo/amo1
Are you sure you want to change the base?
Conversation
This commit adds two Clang builtins for AMO load signed operations: __builtin_amo_lwat_st for 32-bit signed operations __builtin_amo_ldat_s for 64-bit signed operations
|
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-clang Author: Maryam Moghadas (maryammo) ChangesThis commit adds two Clang builtins for AMO load signed operations: __builtin_amo_lwat_st for 32-bit signed operations Full diff: https://github.com/llvm/llvm-project/pull/168747.diff 8 Files Affected:
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index 216b5fdb69ff7..43ba793795d38 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1004,6 +1004,8 @@ TARGET_BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "", "vsx")
// AMO builtins
TARGET_BUILTIN(__builtin_amo_lwat, "UiUi*UiIi", "", "isa-v30-instructions")
TARGET_BUILTIN(__builtin_amo_ldat, "ULiULi*ULiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_lwat_s, "SiSi*SiIi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_amo_ldat_s, "SLiSLi*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 44d5938e38724..1e1127350c301 100644
--- a/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/PPC.cpp
@@ -1359,5 +1359,20 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
{EmitScalarExpr(E->getArg(0))});
case PPC::BI__builtin_ppc_mffs:
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_readflm));
+
+ case PPC::BI__builtin_amo_lwat_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_lwat),
+ {Op0, Op1, Op2});
+ }
+ case PPC::BI__builtin_amo_ldat_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_ldat),
+ {Op0, Op1, Op2});
+ }
}
}
diff --git a/clang/lib/Headers/amo.h b/clang/lib/Headers/amo.h
index fda2984b97626..bdb1ff23f161a 100644
--- a/clang/lib/Headers/amo.h
+++ b/clang/lib/Headers/amo.h
@@ -61,6 +61,23 @@ static inline uint32_t amo_lwat_swap(uint32_t *ptr, uint32_t val) {
return __builtin_amo_lwat(ptr, val, _AMO_LD_SWAP);
}
+/* 32-bit signed AMO load operations */
+static inline int32_t amo_lwat_sadd(int32_t *ptr, int32_t val) {
+ return __builtin_amo_lwat_s(ptr, val, _AMO_LD_ADD);
+}
+
+static inline int32_t amo_lwat_smax(int32_t *ptr, int32_t val) {
+ return __builtin_amo_lwat_s(ptr, val, _AMO_LD_SMAX);
+}
+
+static inline int32_t amo_lwat_smin(int32_t *ptr, int32_t val) {
+ return __builtin_amo_lwat_s(ptr, val, _AMO_LD_SMIN);
+}
+
+static inline int32_t amo_lwat_sswap(int32_t *ptr, int32_t val) {
+ return __builtin_amo_lwat_s(ptr, val, _AMO_LD_SWAP);
+}
+
/* 64-bit unsigned AMO load operations */
static inline uint64_t amo_ldat_add(uint64_t *ptr, uint64_t val) {
return __builtin_amo_ldat(ptr, val, _AMO_LD_ADD);
@@ -90,6 +107,23 @@ static inline uint64_t amo_ldat_swap(uint64_t *ptr, uint64_t val) {
return __builtin_amo_ldat(ptr, val, _AMO_LD_SWAP);
}
+/* 64-bit signed AMO load operations */
+static inline int64_t amo_ldat_sadd(int64_t *ptr, int64_t val) {
+ return __builtin_amo_ldat_s(ptr, val, _AMO_LD_ADD);
+}
+
+static inline int64_t amo_ldat_smax(int64_t *ptr, int64_t val) {
+ return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SMAX);
+}
+
+static inline int64_t amo_ldat_smin(int64_t *ptr, int64_t val) {
+ return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SMIN);
+}
+
+static inline int64_t amo_ldat_sswap(int64_t *ptr, int64_t val) {
+ return __builtin_amo_ldat_s(ptr, val, _AMO_LD_SWAP);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp
index 3d6615b6b5395..dfb423b7b36a4 100644
--- a/clang/lib/Sema/SemaPPC.cpp
+++ b/clang/lib/Sema/SemaPPC.cpp
@@ -256,17 +256,27 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
return BuiltinPPCMMACall(TheCall, BuiltinID, Types);
#include "clang/Basic/BuiltinsPPC.def"
case PPC::BI__builtin_amo_lwat:
- case PPC::BI__builtin_amo_ldat: {
+ case PPC::BI__builtin_amo_ldat:
+ case PPC::BI__builtin_amo_lwat_s:
+ case PPC::BI__builtin_amo_ldat_s: {
llvm::APSInt Result;
if (SemaRef.BuiltinConstantArg(TheCall, 2, Result))
return true;
unsigned Val = Result.getZExtValue();
- static constexpr unsigned ValidFC[] = {0, 1, 2, 3, 4, 6, 8};
- if (llvm::is_contained(ValidFC, Val))
+
+ bool IsUnsigned = (BuiltinID == PPC::BI__builtin_amo_lwat ||
+ BuiltinID == PPC::BI__builtin_amo_ldat);
+
+ bool IsValid = IsUnsigned ? llvm::is_contained({0, 1, 2, 3, 4, 6, 8}, Val)
+ : llvm::is_contained({0, 5, 7, 8}, Val);
+
+ if (IsValid)
return false;
+
Expr *Arg = TheCall->getArg(2);
return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
- << toString(Result, 10) << "0-4, 6" << "8" << Arg->getSourceRange();
+ << toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7") << "8"
+ << 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 cdc14ef7f7e04..217dd58f76736 100644
--- a/clang/test/CodeGen/PowerPC/builtins-amo-err.c
+++ b/clang/test/CodeGen/PowerPC/builtins-amo-err.c
@@ -15,4 +15,16 @@ void test_amo() {
__builtin_amo_ldat(ptr2, value2, 3);
// FC-ERROR: error: argument value 26 is outside the valid range [0-4, 6, 8]
__builtin_amo_ldat(ptr2, value2, 26);
+
+ signed int *ptr3, value3;
+ // AIX32-ERROR: error: this builtin is only available on 64-bit targets
+ __builtin_amo_lwat_s(ptr3, value3, 0);
+ // FC-ERROR: argument value 2 is outside the valid range [0, 5, 7, 8]
+ __builtin_amo_lwat_s(ptr3, value3, 2);
+
+ unsigned long int *ptr4, value4;
+ // AIX32-ERROR: error: this builtin is only available on 64-bit targets
+ __builtin_amo_ldat_s(ptr4, value4, 3);
+ // FC-ERROR: error: argument value 6 is outside the valid range [0, 5, 7, 8]
+ __builtin_amo_ldat_s(ptr4, value4, 6);
}
diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c b/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c
index 2975b99786869..03e71429319b3 100644
--- a/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c
+++ b/clang/test/CodeGen/PowerPC/builtins-ppc-amo.c
@@ -41,6 +41,46 @@ void test_unsigned_ldat(unsigned long int *ptr, unsigned long int value, unsigne
unsigned long int res = __builtin_amo_ldat(ptr, value, 3);
*resp = res;
}
+
+// CHECK-LABEL: define dso_local void @test_signed_lwat(
+// CHECK-SAME: ptr noundef [[PTR:%.*]], i32 noundef signext [[VALUE:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.amo.lwat(ptr [[PTR]], i32 [[VALUE]], i32 5)
+// CHECK-NEXT: store i32 [[TMP0]], ptr [[RESP]], align 4, !tbaa [[INT_TBAA2]]
+// CHECK-NEXT: ret void
+//
+// AIX-LABEL: define void @test_signed_lwat(
+// AIX-SAME: ptr noundef [[PTR:%.*]], i32 noundef signext [[VALUE:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// AIX-NEXT: [[ENTRY:.*:]]
+// AIX-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.amo.lwat(ptr [[PTR]], i32 [[VALUE]], i32 5)
+// AIX-NEXT: store i32 [[TMP0]], ptr [[RESP]], align 4, !tbaa [[INT_TBAA2]]
+// AIX-NEXT: ret void
+//
+void test_signed_lwat(int *ptr, int value, int * resp) {
+ int res = __builtin_amo_lwat_s(ptr, value, 5);
+ *resp = res;
+}
+
+
+// CHECK-LABEL: define dso_local void @test_signed_ldat(
+// CHECK-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.amo.ldat(ptr [[PTR]], i64 [[VALUE]], i32 8)
+// CHECK-NEXT: store i64 [[TMP0]], ptr [[RESP]], align 8, !tbaa [[LONG_TBAA6]]
+// CHECK-NEXT: ret void
+//
+// AIX-LABEL: define void @test_signed_ldat(
+// AIX-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// AIX-NEXT: [[ENTRY:.*:]]
+// AIX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.amo.ldat(ptr [[PTR]], i64 [[VALUE]], i32 8)
+// AIX-NEXT: store i64 [[TMP0]], ptr [[RESP]], align 8, !tbaa [[LONG_TBAA6]]
+// AIX-NEXT: ret void
+//
+void test_signed_ldat(long int *ptr, long int value, long int * resp) {
+ long int res = __builtin_amo_ldat_s(ptr, value, 8);
+ *resp = res;
+}
+
//.
// 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 f544cdef1e7d0..ffc87561fa3c4 100644
--- a/clang/test/CodeGen/PowerPC/ppc-amo-header.c
+++ b/clang/test/CodeGen/PowerPC/ppc-amo-header.c
@@ -48,6 +48,30 @@ uint32_t test_lwat_swap(uint32_t *ptr, uint32_t val) {
return amo_lwat_swap(ptr, val);
}
+int32_t test_lwat_sadd(int32_t *ptr, int32_t val) {
+ // CHECK-LABEL: @test_lwat_sadd
+ // CHECK: call i32 @llvm.ppc.amo.lwat(ptr %{{.*}}, i32 %{{.*}}, i32 0)
+ return amo_lwat_sadd(ptr, val);
+}
+
+int32_t test_lwat_smax(int32_t *ptr, int32_t val) {
+ // CHECK-LABEL: @test_lwat_smax
+ // CHECK: call i32 @llvm.ppc.amo.lwat(ptr %{{.*}}, i32 %{{.*}}, i32 5)
+ return amo_lwat_smax(ptr, val);
+}
+
+int32_t test_lwat_smin(int32_t *ptr, int32_t val) {
+ // CHECK-LABEL: @test_lwat_smin
+ // CHECK: call i32 @llvm.ppc.amo.lwat(ptr %{{.*}}, i32 %{{.*}}, i32 7)
+ return amo_lwat_smin(ptr, val);
+}
+
+int32_t test_lwat_sswap(int32_t *ptr, int32_t val) {
+ // CHECK-LABEL: @test_lwat_sswap
+ // CHECK: call i32 @llvm.ppc.amo.lwat(ptr %{{.*}}, i32 %{{.*}}, i32 8)
+ return amo_lwat_sswap(ptr, val);
+}
+
uint64_t test_ldat_add(uint64_t *ptr, uint64_t val) {
// CHECK-LABEL: @test_ldat_add
// CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 0)
@@ -89,3 +113,27 @@ uint64_t test_ldat_swap(uint64_t *ptr, uint64_t val) {
// CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 8)
return amo_ldat_swap(ptr, val);
}
+
+int64_t test_ldat_sadd(int64_t *ptr, int64_t val) {
+ // CHECK-LABEL: @test_ldat_sadd
+ // CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 0)
+ return amo_ldat_sadd(ptr, val);
+}
+
+int64_t test_ldat_smax(int64_t *ptr, int64_t val) {
+ // CHECK-LABEL: @test_ldat_smax
+ // CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 5)
+ return amo_ldat_smax(ptr, val);
+}
+
+int64_t test_ldat_smin(int64_t *ptr, int64_t val) {
+ // CHECK-LABEL: @test_ldat_smin
+ // CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 7)
+ return amo_ldat_smin(ptr, val);
+}
+
+int64_t test_ldat_sswap(int64_t *ptr, int64_t val) {
+ // CHECK-LABEL: @test_ldat_sswap
+ // CHECK: call i64 @llvm.ppc.amo.ldat(ptr %{{.*}}, i64 %{{.*}}, i32 8)
+ return amo_ldat_sswap(ptr, val);
+}
diff --git a/llvm/test/CodeGen/PowerPC/amo-enable.ll b/llvm/test/CodeGen/PowerPC/amo-enable.ll
index 33739cca12492..37c91e2ff5505 100644
--- a/llvm/test/CodeGen/PowerPC/amo-enable.ll
+++ b/llvm/test/CodeGen/PowerPC/amo-enable.ll
@@ -46,6 +46,45 @@ entry:
ret void
}
+define void @test_s_lwat(ptr noundef %ptr, i32 noundef %value, ptr nocapture %resp) {
+; CHECK-LABEL: test_s_lwat:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mr r7, r4
+; CHECK-NEXT: lwat r6, r3, 0
+; CHECK-NEXT: stw r6, 0(r5)
+; CHECK-NEXT: blr
+;
+; CHECK-BE-LABEL: test_s_lwat:
+; CHECK-BE: # %bb.0: # %entry
+; CHECK-BE-NEXT: mr r7, r4
+; CHECK-BE-NEXT: lwat r6, r3, 0
+; CHECK-BE-NEXT: stw r6, 0(r5)
+; CHECK-BE-NEXT: blr
+entry:
+ %0 = tail call i32 @llvm.ppc.amo.lwat(ptr %ptr, i32 %value, i32 0)
+ store i32 %0, ptr %resp, align 4
+ ret void
+}
+
+define void @test_s_ldat(ptr noundef %ptr, i64 noundef %value, ptr nocapture %resp) {
+; CHECK-LABEL: test_s_ldat:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mr r7, r4
+; CHECK-NEXT: ldat r6, r3, 5
+; CHECK-NEXT: std r6, 0(r5)
+; CHECK-NEXT: blr
+;
+; CHECK-BE-LABEL: test_s_ldat:
+; CHECK-BE: # %bb.0: # %entry
+; CHECK-BE-NEXT: mr r7, r4
+; CHECK-BE-NEXT: ldat r6, r3, 5
+; CHECK-BE-NEXT: std r6, 0(r5)
+; CHECK-BE-NEXT: blr
+entry:
+ %0 = tail call i64 @llvm.ppc.amo.ldat(ptr %ptr, i64 %value, i32 5)
+ store i64 %0, ptr %resp, align 8
+ ret void
+}
+
declare i64 @llvm.ppc.amo.ldat(ptr, i64, i32 immarg)
declare i32 @llvm.ppc.amo.lwat(ptr, i32, i32 immarg)
-
|
This commit adds two Clang builtins for AMO load signed operations:
__builtin_amo_lwat_st for 32-bit signed operations
__builtin_amo_ldat_s for 64-bit signed operations