Skip to content

Commit 71f1352

Browse files
author
Nemanja Ivanovic
committed
[PowerPC][X86] Make cpu id builtins target independent and lower for PPC
Make __builtin_cpu_{init|supports|is} target independent and provide an opt-in query for targets that want to support it. Each target is still responsible for their specific lowering/code-gen. Also provide code-gen for PowerPC.
1 parent 4c6cba3 commit 71f1352

File tree

17 files changed

+443
-82
lines changed

17 files changed

+443
-82
lines changed

clang/include/clang/Basic/Builtins.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@
118118
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
119119
#endif
120120

121+
// Builtins for checking CPU features based on the GCC builtins.
122+
BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
123+
BUILTIN(__builtin_cpu_is, "bcC*", "nc")
124+
BUILTIN(__builtin_cpu_init, "v", "n")
125+
121126
// Standard libc/libm functions:
122127
BUILTIN(__builtin_atan2 , "ddd" , "Fne")
123128
BUILTIN(__builtin_atan2f, "fff" , "Fne")

clang/include/clang/Basic/BuiltinsX86.def

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,6 @@
2626
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
2727
#endif
2828

29-
// Miscellaneous builtin for checking x86 cpu features.
30-
// TODO: Make this somewhat generic so that other backends
31-
// can use it?
32-
BUILTIN(__builtin_cpu_init, "v", "n")
33-
BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
34-
BUILTIN(__builtin_cpu_is, "bcC*", "nc")
35-
3629
// Undefined Values
3730
//
3831
TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "ncV:128:", "")

clang/include/clang/Basic/TargetInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,12 @@ class TargetInfo : public TransferrableTargetInfo,
14151415
getTriple().isOSFreeBSD());
14161416
}
14171417

1418+
// Identify whether this target supports __builtin_cpu_supports and
1419+
// __builtin_cpu_is.
1420+
virtual bool supportsCpuSupports() const { return false; }
1421+
virtual bool supportsCpuIs() const { return false; }
1422+
virtual bool supportsCpuInit() const { return false; }
1423+
14181424
// Validate the contents of the __builtin_cpu_supports(const char*)
14191425
// argument.
14201426
virtual bool validateCpuSupports(StringRef Name) const { return false; }

clang/lib/Basic/Targets/PPC.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,3 +873,17 @@ ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
873873
return llvm::ArrayRef(BuiltinInfo,
874874
clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin);
875875
}
876+
877+
bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const {
878+
#define PPC_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true)
879+
return llvm::StringSwitch<bool>(FeatureStr)
880+
#include "llvm/TargetParser/PPCTargetParser.def"
881+
.Default(false);
882+
}
883+
884+
bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const {
885+
#define PPC_CPU(NAME, NUM) .Case(NAME, true)
886+
return llvm::StringSwitch<bool>(CPUName)
887+
#include "llvm/TargetParser/PPCTargetParser.def"
888+
.Default(false);
889+
}

clang/lib/Basic/Targets/PPC.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,13 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
359359
bool isSPRegName(StringRef RegName) const override {
360360
return RegName.equals("r1") || RegName.equals("x1");
361361
}
362+
363+
// We support __builtin_cpu_supports/__builtin_cpu_is on targets that
364+
// have GLIBC since it is GLIBC that provides the HWCAP[2] in the auxv.
365+
bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); }
366+
bool supportsCpuIs() const override { return getTriple().isOSGlibc(); }
367+
bool validateCpuSupports(StringRef Feature) const override;
368+
bool validateCpuIs(StringRef Name) const override;
362369
};
363370

364371
class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {

clang/lib/Basic/Targets/X86.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
211211
return RegName.equals("esp") || RegName.equals("rsp");
212212
}
213213

214+
bool supportsCpuSupports() const override { return true; }
215+
bool supportsCpuIs() const override { return true; }
216+
bool supportsCpuInit() const override { return true; }
217+
214218
bool validateCpuSupports(StringRef FeatureStr) const override;
215219

216220
bool validateCpuIs(StringRef FeatureStr) const override;

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13585,11 +13585,11 @@ CodeGenFunction::EmitAArch64CpuSupports(ArrayRef<StringRef> FeaturesStrs) {
1358513585

1358613586
Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
1358713587
const CallExpr *E) {
13588-
if (BuiltinID == X86::BI__builtin_cpu_is)
13588+
if (BuiltinID == Builtin::BI__builtin_cpu_is)
1358913589
return EmitX86CpuIs(E);
13590-
if (BuiltinID == X86::BI__builtin_cpu_supports)
13590+
if (BuiltinID == Builtin::BI__builtin_cpu_supports)
1359113591
return EmitX86CpuSupports(E);
13592-
if (BuiltinID == X86::BI__builtin_cpu_init)
13592+
if (BuiltinID == Builtin::BI__builtin_cpu_init)
1359313593
return EmitX86CpuInit();
1359413594

1359513595
// Handle MSVC intrinsics before argument evaluation to prevent double
@@ -16086,6 +16086,42 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
1608616086
switch (BuiltinID) {
1608716087
default: return nullptr;
1608816088

16089+
case Builtin::BI__builtin_cpu_is: {
16090+
const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
16091+
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
16092+
unsigned NumCPUID = StringSwitch<unsigned>(CPUStr)
16093+
#define PPC_CPU(Name, NumericID) .Case(Name, NumericID)
16094+
#include "llvm/TargetParser/PPCTargetParser.def"
16095+
.Default(-1U);
16096+
Value *Op0 =
16097+
llvm::ConstantInt::get(Int32Ty, PPC_FAWORD_CPUID);
16098+
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld);
16099+
Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_is");
16100+
return Builder.CreateICmpEQ(TheCall,
16101+
llvm::ConstantInt::get(Int32Ty, NumCPUID));
16102+
}
16103+
case Builtin::BI__builtin_cpu_supports: {
16104+
unsigned FeatureWord;
16105+
unsigned BitMask;
16106+
const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
16107+
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
16108+
std::tie(FeatureWord, BitMask) =
16109+
StringSwitch<std::pair<unsigned, unsigned>>(CPUStr)
16110+
#define PPC_FEATURE(Name, Description, EnumName, Bitmask, FA_WORD) \
16111+
.Case(Name, {FA_WORD, Bitmask})
16112+
#include "llvm/TargetParser/PPCTargetParser.def"
16113+
.Default({0, 0});
16114+
Value *Op0 = llvm::ConstantInt::get(Int32Ty, FeatureWord);
16115+
llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld);
16116+
Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_supports");
16117+
Value *Mask =
16118+
Builder.CreateAnd(TheCall, llvm::ConstantInt::get(Int32Ty, BitMask));
16119+
return Builder.CreateICmpNE(Mask, llvm::Constant::getNullValue(Int32Ty));
16120+
#undef PPC_FAWORD_HWCAP
16121+
#undef PPC_FAWORD_HWCAP2
16122+
#undef PPC_FAWORD_CPUID
16123+
}
16124+
1608916125
// __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
1609016126
// call __builtin_readcyclecounter.
1609116127
case PPC::BI__builtin_ppc_get_timebase:

clang/lib/Sema/SemaChecking.cpp

Lines changed: 77 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,66 @@ static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc,
21102110
return false;
21112111
}
21122112

2113+
/// SemaBuiltinCpuSupports - Handle __builtin_cpu_supports(char *).
2114+
/// This checks that the target supports __builtin_cpu_supports and
2115+
/// that the string argument is constant and valid.
2116+
static bool SemaBuiltinCpuSupports(Sema &S, const TargetInfo &TI,
2117+
const TargetInfo *AuxTI, CallExpr *TheCall) {
2118+
Expr *Arg = TheCall->getArg(0);
2119+
2120+
const TargetInfo *TheTI = nullptr;
2121+
if (TI.supportsCpuSupports())
2122+
TheTI = &TI;
2123+
else if (AuxTI && AuxTI->supportsCpuSupports())
2124+
TheTI = AuxTI;
2125+
else
2126+
return S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
2127+
<< SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
2128+
2129+
// Check if the argument is a string literal.
2130+
if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts()))
2131+
return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
2132+
<< Arg->getSourceRange();
2133+
2134+
// Check the contents of the string.
2135+
StringRef Feature =
2136+
cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString();
2137+
if (!TheTI->validateCpuSupports(Feature))
2138+
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_supports)
2139+
<< Arg->getSourceRange();
2140+
return false;
2141+
}
2142+
2143+
/// SemaBuiltinCpuIs - Handle __builtin_cpu_is(char *).
2144+
/// This checks that the target supports __builtin_cpu_is and
2145+
/// that the string argument is constant and valid.
2146+
static bool SemaBuiltinCpuIs(Sema &S, const TargetInfo &TI,
2147+
const TargetInfo *AuxTI, CallExpr *TheCall) {
2148+
Expr *Arg = TheCall->getArg(0);
2149+
2150+
const TargetInfo *TheTI = nullptr;
2151+
if (TI.supportsCpuIs())
2152+
TheTI = &TI;
2153+
else if (AuxTI && AuxTI->supportsCpuIs())
2154+
TheTI = AuxTI;
2155+
else
2156+
return S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
2157+
<< SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
2158+
2159+
// Check if the argument is a string literal.
2160+
if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts()))
2161+
return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
2162+
<< Arg->getSourceRange();
2163+
2164+
// Check the contents of the string.
2165+
StringRef Feature =
2166+
cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString();
2167+
if (!TheTI->validateCpuIs(Feature))
2168+
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is)
2169+
<< Arg->getSourceRange();
2170+
return false;
2171+
}
2172+
21132173
ExprResult
21142174
Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
21152175
CallExpr *TheCall) {
@@ -2137,6 +2197,23 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
21372197
}
21382198

21392199
switch (BuiltinID) {
2200+
case Builtin::BI__builtin_cpu_supports:
2201+
if (SemaBuiltinCpuSupports(*this, Context.getTargetInfo(),
2202+
Context.getAuxTargetInfo(), TheCall))
2203+
return ExprError();
2204+
break;
2205+
case Builtin::BI__builtin_cpu_is:
2206+
if (SemaBuiltinCpuIs(*this, Context.getTargetInfo(),
2207+
Context.getAuxTargetInfo(), TheCall))
2208+
return ExprError();
2209+
break;
2210+
case Builtin::BI__builtin_cpu_init:
2211+
if (!Context.getTargetInfo().supportsCpuInit()) {
2212+
Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
2213+
<< SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
2214+
return ExprError();
2215+
}
2216+
break;
21402217
case Builtin::BI__builtin___CFStringMakeConstantString:
21412218
// CFStringMakeConstantString is currently not implemented for GOFF (i.e.,
21422219
// on z/OS) and for XCOFF (i.e., on AIX). Emit unsupported
@@ -5582,47 +5659,6 @@ bool Sema::CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI,
55825659
return false;
55835660
}
55845661

5585-
/// SemaBuiltinCpuSupports - Handle __builtin_cpu_supports(char *).
5586-
/// This checks that the target supports __builtin_cpu_supports and
5587-
/// that the string argument is constant and valid.
5588-
static bool SemaBuiltinCpuSupports(Sema &S, const TargetInfo &TI,
5589-
CallExpr *TheCall) {
5590-
Expr *Arg = TheCall->getArg(0);
5591-
5592-
// Check if the argument is a string literal.
5593-
if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts()))
5594-
return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
5595-
<< Arg->getSourceRange();
5596-
5597-
// Check the contents of the string.
5598-
StringRef Feature =
5599-
cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString();
5600-
if (!TI.validateCpuSupports(Feature))
5601-
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_supports)
5602-
<< Arg->getSourceRange();
5603-
return false;
5604-
}
5605-
5606-
/// SemaBuiltinCpuIs - Handle __builtin_cpu_is(char *).
5607-
/// This checks that the target supports __builtin_cpu_is and
5608-
/// that the string argument is constant and valid.
5609-
static bool SemaBuiltinCpuIs(Sema &S, const TargetInfo &TI, CallExpr *TheCall) {
5610-
Expr *Arg = TheCall->getArg(0);
5611-
5612-
// Check if the argument is a string literal.
5613-
if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts()))
5614-
return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
5615-
<< Arg->getSourceRange();
5616-
5617-
// Check the contents of the string.
5618-
StringRef Feature =
5619-
cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString();
5620-
if (!TI.validateCpuIs(Feature))
5621-
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is)
5622-
<< Arg->getSourceRange();
5623-
return false;
5624-
}
5625-
56265662
// Check if the rounding mode is legal.
56275663
bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) {
56285664
// Indicates if this instruction has rounding control or just SAE.
@@ -6097,12 +6133,6 @@ static bool isX86_32Builtin(unsigned BuiltinID) {
60976133

60986134
bool Sema::CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
60996135
CallExpr *TheCall) {
6100-
if (BuiltinID == X86::BI__builtin_cpu_supports)
6101-
return SemaBuiltinCpuSupports(*this, TI, TheCall);
6102-
6103-
if (BuiltinID == X86::BI__builtin_cpu_is)
6104-
return SemaBuiltinCpuIs(*this, TI, TheCall);
6105-
61066136
// Check for 32-bit only builtins on a 64-bit target.
61076137
const llvm::Triple &TT = TI.getTriple();
61086138
if (TT.getArch() != llvm::Triple::x86 && isX86_32Builtin(BuiltinID))
Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm < %s| FileCheck %s
1+
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm < %s | FileCheck %s \
2+
// RUN: --check-prefix=CHECK-X86
3+
// RUN: %clang_cc1 -triple ppc64le-linux-gnu -emit-llvm < %s | FileCheck %s \
4+
// RUN: --check-prefix=CHECK-PPC
5+
6+
#ifndef __PPC__
27

38
// Test that we have the structure definition, the gep offsets, the name of the
49
// global, the bit grab, and the icmp correct.
510
extern void a(const char *);
611

7-
// CHECK: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
8-
// CHECK: @__cpu_features2 = external dso_local global [3 x i32]
12+
// CHECK-X86: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
13+
// CHECK-X86: @__cpu_features2 = external dso_local global [3 x i32]
914

1015
int main(void) {
1116
__builtin_cpu_init();
@@ -15,38 +20,57 @@ int main(void) {
1520
if (__builtin_cpu_supports("sse4.2"))
1621
a("sse4.2");
1722

18-
// CHECK: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0)
19-
// CHECK: [[AND:%[^ ]+]] = and i32 [[LOAD]], 256
20-
// CHECK: = icmp eq i32 [[AND]], 256
23+
// CHECK-X86: [[LOAD:%[^ ]+]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0)
24+
// CHECK-X86: [[AND:%[^ ]+]] = and i32 [[LOAD]], 256
25+
// CHECK-X86: = icmp eq i32 [[AND]], 256
2126

2227
if (__builtin_cpu_supports("gfni"))
2328
a("gfni");
2429

25-
// CHECK: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
26-
// CHECK: [[AND:%[^ ]+]] = and i32 [[LOAD]], 1
27-
// CHECK: = icmp eq i32 [[AND]], 1
30+
// CHECK-X86: [[LOAD:%[^ ]+]] = load i32, ptr @__cpu_features2
31+
// CHECK-X86: [[AND:%[^ ]+]] = and i32 [[LOAD]], 1
32+
// CHECK-X86: = icmp eq i32 [[AND]], 1
2833

2934
return 0;
3035
}
3136

32-
// CHECK: declare dso_local void @__cpu_indicator_init()
37+
// CHECK-X86: declare dso_local void @__cpu_indicator_init()
3338

34-
// CHECK-LABEL: define{{.*}} @baseline(
35-
// CHECK: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 1)
36-
// CHECK-NEXT: and i32 [[LOAD]], -2147483648
39+
// CHECK-X86-LABEL: define{{.*}} @baseline(
40+
// CHECK-X86: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 1)
41+
// CHECK-X86-NEXT: and i32 [[LOAD]], -2147483648
3742
int baseline() { return __builtin_cpu_supports("x86-64"); }
3843

39-
// CHECK-LABEL: define{{.*}} @v2(
40-
// CHECK: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 2)
41-
// CHECK-NEXT: and i32 [[LOAD]], 1
44+
// CHECK-X86-LABEL: define{{.*}} @v2(
45+
// CHECK-X86: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 2)
46+
// CHECK-X86-NEXT: and i32 [[LOAD]], 1
4247
int v2() { return __builtin_cpu_supports("x86-64-v2"); }
4348

44-
// CHECK-LABEL: define{{.*}} @v3(
45-
// CHECK: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 2)
46-
// CHECK-NEXT: and i32 [[LOAD]], 2
49+
// CHECK-X86-LABEL: define{{.*}} @v3(
50+
// CHECK-X86: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 2)
51+
// CHECK-X86-NEXT: and i32 [[LOAD]], 2
4752
int v3() { return __builtin_cpu_supports("x86-64-v3"); }
4853

49-
// CHECK-LABEL: define{{.*}} @v4(
50-
// CHECK: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 2)
51-
// CHECK-NEXT: and i32 [[LOAD]], 4
54+
// CHECK-X86-LABEL: define{{.*}} @v4(
55+
// CHECK-X86: [[LOAD:%.*]] = load i32, ptr getelementptr inbounds ([[[#]] x i32], ptr @__cpu_features2, i32 0, i32 2)
56+
// CHECK-X86-NEXT: and i32 [[LOAD]], 4
5257
int v4() { return __builtin_cpu_supports("x86-64-v4"); }
58+
#else
59+
int test(int a) {
60+
// CHECK-PPC: [[CPUSUP:%[^ ]+]] = call i32 @llvm.ppc.fixed.addr.ld(i32 2)
61+
// CHECK-PPC: [[AND:%[^ ]+]] = and i32 [[CPUSUP]], 8388608
62+
// CHECK-PPC: icmp ne i32 [[AND]], 0
63+
// CHECK-PPC: [[CPUSUP2:%[^ ]+]] = call i32 @llvm.ppc.fixed.addr.ld(i32 1)
64+
// CHECK-PPC: [[AND2:%[^ ]+]] = and i32 [[CPUSUP2]], 67108864
65+
// CHECK-PPC: icmp ne i32 [[AND2]], 0
66+
// CHECK-PPC: [[CPUID:%[^ ]+]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
67+
// CHECK-PPC: icmp eq i32 [[CPUID]], 39
68+
if (__builtin_cpu_supports("arch_3_00")) // HWCAP2
69+
return a;
70+
else if (__builtin_cpu_supports("mmu")) // HWCAP
71+
return a - 5;
72+
else if (__builtin_cpu_is("power7")) // CPUID
73+
return a + a;
74+
return a + 5;
75+
}
76+
#endif

0 commit comments

Comments
 (0)