Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/BuiltinsPPC.def
Original file line number Diff line number Diff line change
Expand Up @@ -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", "")
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/CodeGen/TargetBuiltins/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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});
}
}
}
34 changes: 34 additions & 0 deletions clang/lib/Headers/amo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
21 changes: 17 additions & 4 deletions clang/lib/Sema/SemaPPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
case PPC::BI__builtin_ppc_fetch_and_swaplp:
case PPC::BI__builtin_amo_lwat:
case PPC::BI__builtin_amo_ldat:
case PPC::BI__builtin_amo_lwat_s:
case PPC::BI__builtin_amo_ldat_s:
return true;
}
return false;
Expand Down Expand Up @@ -256,17 +258,28 @@ 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({0u, 1u, 2u, 3u, 4u, 6u, 8u}, Val)
: llvm::is_contained({0u, 5u, 7u, 8u}, 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");
Expand Down
16 changes: 14 additions & 2 deletions clang/test/CodeGen/PowerPC/builtins-amo-err.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@

void test_amo() {
unsigned int *ptr1, value1;
// AIX32-ERROR: error: this builtin is only available on 64-bit targets
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
__builtin_amo_lwat(ptr1, value1, 0);
// FC-ERROR: argument value 9 is outside the valid range [0-4, 6, 8]
__builtin_amo_lwat(ptr1, value1, 9);

unsigned long int *ptr2, value2;
// AIX32-ERROR: error: this builtin is only available on 64-bit targets
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
__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-COUNT-2: 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);

signed long int *ptr4, value4;
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
__builtin_amo_ldat_s(ptr4, value4, 5);
// FC-ERROR: error: argument value 6 is outside the valid range [0, 5, 7, 8]
__builtin_amo_ldat_s(ptr4, value4, 6);
}
40 changes: 40 additions & 0 deletions clang/test/CodeGen/PowerPC/builtins-ppc-amo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
48 changes: 48 additions & 0 deletions clang/test/CodeGen/PowerPC/ppc-amo-header.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
41 changes: 40 additions & 1 deletion llvm/test/CodeGen/PowerPC/amo-enable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Loading