Skip to content

Commit 8947947

Browse files
author
Nemanja Ivanovic
committed
Address comments
- Use script for generating test checks - Clean up code and rename macros for clarity - Remove magic number offsets - Get rid of auxiliary targets in Sema checking - Clarify some comments and add missing ones - Add check for undefined symbol added for safety
1 parent b817566 commit 8947947

File tree

9 files changed

+294
-171
lines changed

9 files changed

+294
-171
lines changed

clang/lib/Basic/Targets/PPC.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -875,14 +875,14 @@ ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
875875
}
876876

877877
bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const {
878-
#define PPC_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true)
878+
#define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true)
879879
return llvm::StringSwitch<bool>(FeatureStr)
880880
#include "llvm/TargetParser/PPCTargetParser.def"
881881
.Default(false);
882882
}
883883

884884
bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const {
885-
#define PPC_CPU(NAME, NUM) .Case(NAME, true)
885+
#define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true)
886886
return llvm::StringSwitch<bool>(CPUName)
887887
#include "llvm/TargetParser/PPCTargetParser.def"
888888
.Default(false);

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16090,7 +16090,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
1609016090
const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
1609116091
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
1609216092
unsigned NumCPUID = StringSwitch<unsigned>(CPUStr)
16093-
#define PPC_CPU(Name, NumericID) .Case(Name, NumericID)
16093+
#define PPC_LNX_CPU(Name, NumericID) .Case(Name, NumericID)
1609416094
#include "llvm/TargetParser/PPCTargetParser.def"
1609516095
.Default(-1U);
1609616096
Value *Op0 = llvm::ConstantInt::get(Int32Ty, PPC_FAWORD_CPUID);
@@ -16106,7 +16106,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
1610616106
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
1610716107
std::tie(FeatureWord, BitMask) =
1610816108
StringSwitch<std::pair<unsigned, unsigned>>(CPUStr)
16109-
#define PPC_FEATURE(Name, Description, EnumName, Bitmask, FA_WORD) \
16109+
#define PPC_LNX_FEATURE(Name, Description, EnumName, Bitmask, FA_WORD) \
1611016110
.Case(Name, {FA_WORD, Bitmask})
1611116111
#include "llvm/TargetParser/PPCTargetParser.def"
1611216112
.Default({0, 0});

clang/lib/Sema/SemaChecking.cpp

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,61 +2110,35 @@ 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
2113+
/// SemaBuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
2114+
/// This checks that the target supports the builtin and that the string
2115+
/// argument is constant and valid.
2116+
static bool SemaBuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall,
2117+
unsigned BuiltinID) {
2118+
assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2119+
BuiltinID == Builtin::BI__builtin_cpu_is) &&
2120+
"Expecting __builtin_cpu_...");
2121+
2122+
bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2123+
if (IsCPUSupports && !TI.supportsCpuSupports())
21262124
return S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
21272125
<< 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
2126+
if (!IsCPUSupports && !TI.supportsCpuIs())
21562127
return S.Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
21572128
<< SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
21582129

2130+
Expr *Arg = TheCall->getArg(0)->IgnoreParenImpCasts();
21592131
// Check if the argument is a string literal.
2160-
if (!isa<StringLiteral>(Arg->IgnoreParenImpCasts()))
2132+
if (!isa<StringLiteral>(Arg))
21612133
return S.Diag(TheCall->getBeginLoc(), diag::err_expr_not_string_literal)
21622134
<< Arg->getSourceRange();
21632135

21642136
// Check the contents of the string.
2165-
StringRef Feature =
2166-
cast<StringLiteral>(Arg->IgnoreParenImpCasts())->getString();
2167-
if (!TheTI->validateCpuIs(Feature))
2137+
StringRef Feature = cast<StringLiteral>(Arg)->getString();
2138+
if (IsCPUSupports && !TI.validateCpuSupports(Feature))
2139+
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_supports)
2140+
<< Arg->getSourceRange();
2141+
if (!IsCPUSupports && !TI.validateCpuIs(Feature))
21682142
return S.Diag(TheCall->getBeginLoc(), diag::err_invalid_cpu_is)
21692143
<< Arg->getSourceRange();
21702144
return false;
@@ -2198,13 +2172,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
21982172

21992173
switch (BuiltinID) {
22002174
case Builtin::BI__builtin_cpu_supports:
2201-
if (SemaBuiltinCpuSupports(*this, Context.getTargetInfo(),
2202-
Context.getAuxTargetInfo(), TheCall))
2203-
return ExprError();
2204-
break;
22052175
case Builtin::BI__builtin_cpu_is:
2206-
if (SemaBuiltinCpuIs(*this, Context.getTargetInfo(),
2207-
Context.getAuxTargetInfo(), TheCall))
2176+
if (SemaBuiltinCpu(*this, Context.getTargetInfo(), TheCall, BuiltinID))
22082177
return ExprError();
22092178
break;
22102179
case Builtin::BI__builtin_cpu_init:

clang/test/CodeGen/builtin-cpu-supports.c

Lines changed: 117 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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 \
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3
2+
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s | \
3+
// RUN: FileCheck %s --check-prefix=CHECK-X86
4+
// RUN: %clang_cc1 -triple ppc64le-linux-gnu -emit-llvm -o - %s | FileCheck %s \
45
// RUN: --check-prefix=CHECK-PPC
56

67
#ifndef __PPC__
@@ -9,9 +10,33 @@
910
// global, the bit grab, and the icmp correct.
1011
extern void a(const char *);
1112

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]
1413

14+
// CHECK-X86-LABEL: define dso_local i32 @main(
15+
// CHECK-X86-SAME: ) #[[ATTR0:[0-9]+]] {
16+
// CHECK-X86-NEXT: entry:
17+
// CHECK-X86-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
18+
// CHECK-X86-NEXT: store i32 0, ptr [[RETVAL]], align 4
19+
// CHECK-X86-NEXT: call void @__cpu_indicator_init()
20+
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds ({ i32, i32, i32, [1 x i32] }, ptr @__cpu_model, i32 0, i32 3, i32 0), align 4
21+
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 256
22+
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 256
23+
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
24+
// CHECK-X86-NEXT: br i1 [[TMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
25+
// CHECK-X86: if.then:
26+
// CHECK-X86-NEXT: call void @a(ptr noundef @.str)
27+
// CHECK-X86-NEXT: br label [[IF_END]]
28+
// CHECK-X86: if.end:
29+
// CHECK-X86-NEXT: [[TMP4:%.*]] = load i32, ptr @__cpu_features2, align 4
30+
// CHECK-X86-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1
31+
// CHECK-X86-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 1
32+
// CHECK-X86-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]]
33+
// CHECK-X86-NEXT: br i1 [[TMP7]], label [[IF_THEN1:%.*]], label [[IF_END2:%.*]]
34+
// CHECK-X86: if.then1:
35+
// CHECK-X86-NEXT: call void @a(ptr noundef @.str.1)
36+
// CHECK-X86-NEXT: br label [[IF_END2]]
37+
// CHECK-X86: if.end2:
38+
// CHECK-X86-NEXT: ret i32 0
39+
//
1540
int main(void) {
1641
__builtin_cpu_init();
1742

@@ -20,51 +45,111 @@ int main(void) {
2045
if (__builtin_cpu_supports("sse4.2"))
2146
a("sse4.2");
2247

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
2648

2749
if (__builtin_cpu_supports("gfni"))
2850
a("gfni");
2951

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
3352

3453
return 0;
3554
}
3655

37-
// CHECK-X86: declare dso_local void @__cpu_indicator_init()
3856

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
57+
// CHECK-X86-LABEL: define dso_local i32 @baseline(
58+
// CHECK-X86-SAME: ) #[[ATTR0]] {
59+
// CHECK-X86-NEXT: entry:
60+
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 1), align 4
61+
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], -2147483648
62+
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -2147483648
63+
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
64+
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
65+
// CHECK-X86-NEXT: ret i32 [[CONV]]
66+
//
4267
int baseline() { return __builtin_cpu_supports("x86-64"); }
4368

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
69+
// CHECK-X86-LABEL: define dso_local i32 @v2(
70+
// CHECK-X86-SAME: ) #[[ATTR0]] {
71+
// CHECK-X86-NEXT: entry:
72+
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2), align 4
73+
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 1
74+
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
75+
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
76+
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
77+
// CHECK-X86-NEXT: ret i32 [[CONV]]
78+
//
4779
int v2() { return __builtin_cpu_supports("x86-64-v2"); }
4880

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
81+
// CHECK-X86-LABEL: define dso_local i32 @v3(
82+
// CHECK-X86-SAME: ) #[[ATTR0]] {
83+
// CHECK-X86-NEXT: entry:
84+
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2), align 4
85+
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 2
86+
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 2
87+
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
88+
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
89+
// CHECK-X86-NEXT: ret i32 [[CONV]]
90+
//
5291
int v3() { return __builtin_cpu_supports("x86-64-v3"); }
5392

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
93+
// CHECK-X86-LABEL: define dso_local i32 @v4(
94+
// CHECK-X86-SAME: ) #[[ATTR0]] {
95+
// CHECK-X86-NEXT: entry:
96+
// CHECK-X86-NEXT: [[TMP0:%.*]] = load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2), align 4
97+
// CHECK-X86-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 4
98+
// CHECK-X86-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4
99+
// CHECK-X86-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
100+
// CHECK-X86-NEXT: [[CONV:%.*]] = zext i1 [[TMP3]] to i32
101+
// CHECK-X86-NEXT: ret i32 [[CONV]]
102+
//
57103
int v4() { return __builtin_cpu_supports("x86-64-v4"); }
58104
#else
105+
// CHECK-PPC-LABEL: define dso_local signext i32 @test(
106+
// CHECK-PPC-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
107+
// CHECK-PPC-NEXT: entry:
108+
// CHECK-PPC-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
109+
// CHECK-PPC-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
110+
// CHECK-PPC-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4
111+
// CHECK-PPC-NEXT: [[CPU_SUPPORTS:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 2)
112+
// CHECK-PPC-NEXT: [[TMP0:%.*]] = and i32 [[CPU_SUPPORTS]], 8388608
113+
// CHECK-PPC-NEXT: [[TMP1:%.*]] = icmp ne i32 [[TMP0]], 0
114+
// CHECK-PPC-NEXT: br i1 [[TMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
115+
// CHECK-PPC: if.then:
116+
// CHECK-PPC-NEXT: [[TMP2:%.*]] = load i32, ptr [[A_ADDR]], align 4
117+
// CHECK-PPC-NEXT: store i32 [[TMP2]], ptr [[RETVAL]], align 4
118+
// CHECK-PPC-NEXT: br label [[RETURN:%.*]]
119+
// CHECK-PPC: if.else:
120+
// CHECK-PPC-NEXT: [[CPU_SUPPORTS1:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 1)
121+
// CHECK-PPC-NEXT: [[TMP3:%.*]] = and i32 [[CPU_SUPPORTS1]], 67108864
122+
// CHECK-PPC-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0
123+
// CHECK-PPC-NEXT: br i1 [[TMP4]], label [[IF_THEN2:%.*]], label [[IF_ELSE3:%.*]]
124+
// CHECK-PPC: if.then2:
125+
// CHECK-PPC-NEXT: [[TMP5:%.*]] = load i32, ptr [[A_ADDR]], align 4
126+
// CHECK-PPC-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP5]], 5
127+
// CHECK-PPC-NEXT: store i32 [[SUB]], ptr [[RETVAL]], align 4
128+
// CHECK-PPC-NEXT: br label [[RETURN]]
129+
// CHECK-PPC: if.else3:
130+
// CHECK-PPC-NEXT: [[CPU_IS:%.*]] = call i32 @llvm.ppc.fixed.addr.ld(i32 3)
131+
// CHECK-PPC-NEXT: [[TMP6:%.*]] = icmp eq i32 [[CPU_IS]], 39
132+
// CHECK-PPC-NEXT: br i1 [[TMP6]], label [[IF_THEN4:%.*]], label [[IF_END:%.*]]
133+
// CHECK-PPC: if.then4:
134+
// CHECK-PPC-NEXT: [[TMP7:%.*]] = load i32, ptr [[A_ADDR]], align 4
135+
// CHECK-PPC-NEXT: [[TMP8:%.*]] = load i32, ptr [[A_ADDR]], align 4
136+
// CHECK-PPC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP7]], [[TMP8]]
137+
// CHECK-PPC-NEXT: store i32 [[ADD]], ptr [[RETVAL]], align 4
138+
// CHECK-PPC-NEXT: br label [[RETURN]]
139+
// CHECK-PPC: if.end:
140+
// CHECK-PPC-NEXT: br label [[IF_END5:%.*]]
141+
// CHECK-PPC: if.end5:
142+
// CHECK-PPC-NEXT: br label [[IF_END6:%.*]]
143+
// CHECK-PPC: if.end6:
144+
// CHECK-PPC-NEXT: [[TMP9:%.*]] = load i32, ptr [[A_ADDR]], align 4
145+
// CHECK-PPC-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP9]], 5
146+
// CHECK-PPC-NEXT: store i32 [[ADD7]], ptr [[RETVAL]], align 4
147+
// CHECK-PPC-NEXT: br label [[RETURN]]
148+
// CHECK-PPC: return:
149+
// CHECK-PPC-NEXT: [[TMP10:%.*]] = load i32, ptr [[RETVAL]], align 4
150+
// CHECK-PPC-NEXT: ret i32 [[TMP10]]
151+
//
59152
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
68153
if (__builtin_cpu_supports("arch_3_00")) // HWCAP2
69154
return a;
70155
else if (__builtin_cpu_supports("mmu")) // HWCAP

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
211211
[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_vararg_ty],
212212
[IntrNoMem]>;
213213
// Load of a value provided by the system library at a fixed address. Used for
214-
// accessing things like HWCAP word provided by GLIBC.
214+
// accessing things like HWCAP word provided by GLIBC. The immediate argument
215+
// is not an address but a value defined in
216+
// include/llvm/TargetParser/PPCTargetParser.def. Each of the values provided
217+
// by Glibc is a 32-bit word.
215218
def int_ppc_fixed_addr_ld
216219
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty],
217220
[IntrInaccessibleMemOnly, ImmArg<ArgIndex<0>>]>;

0 commit comments

Comments
 (0)