// REQUIRES: powerpc-registered-target
// RUN: %clang_cc1 -no-opaque-pointers -triple powerpc64-unknown-linux-gnu \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefixes=64BIT --check-prefix=BOTH
// RUN: %clang_cc1 -no-opaque-pointers -triple powerpc64le-unknown-linux-gnu \
// RUN: -emit-llvm %s -o - -target-cpu pwr8 | FileCheck %s --check-prefixes=64BIT --check-prefix=BOTH
// RUN: %clang_cc1 -no-opaque-pointers -triple powerpc-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefixes=32BIT --check-prefix=BOTH
// RUN: %clang_cc1 -no-opaque-pointers -triple powerpc64-unknown-aix \
// RUN: -emit-llvm %s -o - -target-cpu pwr7 | FileCheck %s --check-prefixes=64BIT --check-prefix=BOTH
// Will not be adding include files to avoid any dependencies on the system.
// Required for size_t. Usually found in stddef.h.
typedef __SIZE_TYPE__ size_t;
// BOTH-LABEL: @testabs(
// BOTH-NEXT: entry:
// BOTH-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// BOTH-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// BOTH-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
// BOTH-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
// BOTH-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
// BOTH-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
// BOTH-NEXT: ret i32 [[ABS]]
signed int
// 64BIT-LABEL: @testlabs(
// 64BIT-NEXT: entry:
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
// 64BIT-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
// 64BIT-NEXT: ret i64 [[ABS]]
//
// 32BIT-LABEL: @testlabs(
// 32BIT-NEXT: entry:
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
// 32BIT-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
// 32BIT-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[TMP0]]
// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i32 [[TMP0]], 0
// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[TMP0]]
// 32BIT-NEXT: ret i32 [[ABS]]
//
signed long
// 64BIT-LABEL: @testllabs(
// 64BIT-NEXT: entry:
// 64BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
// 64BIT-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// 64BIT-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
// 64BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
// 64BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
// 64BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
// 64BIT-NEXT: ret i64 [[ABS]]
//
// 32BIT-LABEL: @testllabs(
// 32BIT-NEXT: entry:
// 32BIT-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
// 32BIT-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
// 32BIT-NEXT: [[TMP0:%.*]] = load i64, i64* [[A_ADDR]], align 8
// 32BIT-NEXT: [[NEG:%.*]] = sub nsw i64 0, [[TMP0]]
// 32BIT-NEXT: [[ABSCOND:%.*]] = icmp slt i64 [[TMP0]], 0
// 32BIT-NEXT: [[ABS:%.*]] = select i1 [[ABSCOND]], i64 [[NEG]], i64 [[TMP0]]
// 32BIT-NEXT: ret i64 [[ABS]]
//
signed long long
// 64BIT-LABEL: @testalloca(
// 64BIT: [[TMP1:%.*]] = alloca i8, i64
// 64BIT-NEXT: ret i8* [[TMP1]]
//
// 32BIT-LABEL: @testalloca(
// 32BIT: [[TMP1:%.*]] = alloca i8, i32
// 32BIT-NEXT: ret i8* [[TMP1]]
//
void *
// Note that bpermd is 64 bit only.
// 64BIT-LABEL: @testbpermd(
// 64BIT: [[TMP:%.*]] = call i64 @llvm.ppc.bpermd(i64 {{%.*}}, i64 {{%.*}})
// 64BIT-NEXT: ret i64 [[TMP]]
//
long long
// 64BIT-LABEL: @testdivde(
// 64BIT: [[TMP2:%.*]] = call i64 @llvm.ppc.divde
// 64BIT-NEXT: ret i64 [[TMP2]]
long long
// 64BIT-LABEL: @testdivdeu(
// 64BIT: [[TMP2:%.*]] = call i64 @llvm.ppc.divdeu
// 64BIT-NEXT: ret i64 [[TMP2]]
unsigned long long
// 64BIT-LABEL: @testdivwe(
// 64BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divwe
// 64BIT-NEXT: ret i32 [[TMP2]]
//
// 32BIT-LABEL: @testdivwe(
// 32BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divwe
// 32BIT-NEXT: ret i32 [[TMP2]]
int
// 64BIT-LABEL: @testdivweu(
// 64BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divweu
// 64BIT-NEXT: ret i32 [[TMP2]]
//
// 32BIT-LABEL: @testdivweu(
// 32BIT: [[TMP2:%.*]] = call i32 @llvm.ppc.divweu
// 32BIT-NEXT: ret i32 [[TMP2]]
unsigned int
// BOTH-LABEL: @testfmadd(
// BOTH: [[TMP3:%.*]] = call double @llvm.fma.f64
// BOTH-NEXT: ret double [[TMP3]]
//
double
// BOTH-LABEL: @testfmadds(
// BOTH: [[TMP3:%.*]] = call float @llvm.fma.f32(
// BOTH-NEXT: ret float [[TMP3]]
//
float
// Required for bzero and bcopy. Usually in strings.h.
extern void ;
extern void ;
// 64BIT-LABEL: @testalignx(
// 64BIT: call void @llvm.assume(i1 true) [ "align"(i8* {{%.*}}, i64 16) ]
// 64BIT-NEXT: ret void
//
// 32BIT-LABEL: @testalignx(
// 32BIT: call void @llvm.assume(i1 true) [ "align"(i8* {{%.*}}, i32 16) ]
// 32BIT-NEXT: ret void
//
void
// 64BIT-LABEL: @testbcopy(
// 64BIT: call void @bcopy(i8* noundef {{%.*}}, i8* noundef {{%.*}}, i64 noundef {{%.*}})
// 64BIT-NEXT: ret void
//
// 32BIT-LABEL: @testbcopy(
// 32BIT: call void @bcopy(i8* noundef {{%.*}}, i8* noundef {{%.*}}, i32 noundef {{%.*}})
// 32BIT-NEXT: ret void
//
void
// 64BIT-LABEL: @testbzero(
// 64BIT: call void @llvm.memset.p0i8.i64(i8* align 1 {{%.*}}, i8 0, i64 {{%.*}}, i1 false)
// 64BIT-NEXT: ret void
//
// 32BIT-LABEL: @testbzero(
// 32BIT: call void @llvm.memset.p0i8.i32(i8* align 1 {{%.*}}, i8 0, i32 {{%.*}}, i1 false)
// 32BIT-NEXT: ret void
//
void
// 64BIT-LABEL: @testdcbf(
// 64BIT: call void @llvm.ppc.dcbf(i8* {{%.*}})
// 64BIT-NEXT: ret void
//
// 32BIT-LABEL: @testdcbf(
// 32BIT: call void @llvm.ppc.dcbf(i8* {{%.*}})
// 32BIT-NEXT: ret void
//
void
// BOTH-LABEL: @testreadflm(
// BOTH: [[TMP0:%.*]] = call double @llvm.ppc.readflm()
// BOTH-NEXT: ret double [[TMP0]]
//
double
// BOTH-LABEL: @testsetflm(
// BOTH: [[TMP1:%.*]] = call double @llvm.ppc.setflm(double {{%.*}})
// BOTH-NEXT: ret double [[TMP1]]
//
double
// BOTH-LABEL: @testsetrnd(
// BOTH: [[TMP1:%.*]] = call double @llvm.ppc.setrnd(i32 {{%.*}})
// BOTH-NEXT: ret double [[TMP1]]
//
double