@@ -62,9 +62,9 @@ class PNaClABIVerifyModule : public ModulePass {
62
62
bool runOnModule (Module &M);
63
63
virtual void print (raw_ostream &O, const Module *M) const ;
64
64
private:
65
- void CheckGlobalValueCommon (const GlobalValue *GV);
66
- bool IsWhitelistedIntrinsic (const Function* F, unsigned ID);
67
- bool IsWhitelistedMetadata (const NamedMDNode *MD);
65
+ void checkGlobalValueCommon (const GlobalValue *GV);
66
+ bool isWhitelistedIntrinsic (const Function * F, unsigned ID);
67
+ bool isWhitelistedMetadata (const NamedMDNode *MD);
68
68
PNaClABITypeChecker TC;
69
69
PNaClABIErrorReporter *Reporter;
70
70
bool ReporterIsOwned;
@@ -100,7 +100,7 @@ static const char *linkageName(GlobalValue::LinkageTypes LT) {
100
100
101
101
// Check linkage type and section attributes, which are the same for
102
102
// GlobalVariables and Functions.
103
- void PNaClABIVerifyModule::CheckGlobalValueCommon (const GlobalValue *GV) {
103
+ void PNaClABIVerifyModule::checkGlobalValueCommon (const GlobalValue *GV) {
104
104
assert (!isa<GlobalAlias>(GV));
105
105
const char *GVTypeName = isa<GlobalVariable>(GV) ?
106
106
" Variable " : " Function " ;
@@ -122,7 +122,32 @@ void PNaClABIVerifyModule::CheckGlobalValueCommon(const GlobalValue *GV) {
122
122
}
123
123
}
124
124
125
- bool PNaClABIVerifyModule::IsWhitelistedIntrinsic (const Function* F,
125
+ static bool TypeAcceptable (const Type *T,
126
+ const ArrayRef<Type*> &AcceptableTypes) {
127
+ for (ArrayRef<Type*>::iterator I = AcceptableTypes.begin (),
128
+ E = AcceptableTypes.end (); I != E; ++I)
129
+ if (*I == T)
130
+ return true ;
131
+ return false ;
132
+ }
133
+
134
+ // We accept bswap for a limited set of types (i16, i32, i64).
135
+ // The various backends are able to generate instructions to
136
+ // implement the intrinsic. Also, i16 and i64 are easy to
137
+ // implement as along as there is a way to do i32.
138
+ static bool isWhitelistedBswap (const Function *F) {
139
+ FunctionType *FT = F->getFunctionType ();
140
+ if (FT->getNumParams () != 1 )
141
+ return false ;
142
+ Type *ParamType = FT->getParamType (0 );
143
+ LLVMContext &C = F->getContext ();
144
+ Type *AcceptableTypes[] = { Type::getInt16Ty (C),
145
+ Type::getInt32Ty (C),
146
+ Type::getInt64Ty (C) };
147
+ return TypeAcceptable (ParamType, AcceptableTypes);
148
+ }
149
+
150
+ bool PNaClABIVerifyModule::isWhitelistedIntrinsic (const Function *F,
126
151
unsigned ID) {
127
152
// Keep 3 categories of intrinsics for now.
128
153
// (1) Allowed always
@@ -135,6 +160,7 @@ bool PNaClABIVerifyModule::IsWhitelistedIntrinsic(const Function* F,
135
160
// Disallow by default.
136
161
default : return false ;
137
162
// (1) Always allowed.
163
+ case Intrinsic::bswap: return isWhitelistedBswap (F);
138
164
case Intrinsic::invariant_end:
139
165
case Intrinsic::invariant_start:
140
166
case Intrinsic::lifetime_end:
@@ -179,15 +205,16 @@ bool PNaClABIVerifyModule::IsWhitelistedIntrinsic(const Function* F,
179
205
case Intrinsic::dbg_declare:
180
206
case Intrinsic::dbg_value:
181
207
return PNaClABIAllowDevIntrinsics || PNaClABIAllowDebugMetadata;
182
- case Intrinsic::bswap: // Support via compiler_rt if arch doesn't have it?
183
208
case Intrinsic::cos : // Rounding not defined: support with fast-math?
184
209
case Intrinsic::ctlz: // Support via compiler_rt if arch doesn't have it?
185
210
case Intrinsic::ctpop: // Support via compiler_rt if arch doesn't have it?
186
211
case Intrinsic::cttz: // Support via compiler_rt if arch doesn't have it?
187
212
case Intrinsic::exp : // Rounding not defined: support with fast-math?
188
213
case Intrinsic::exp2 : // Rounding not defined: support with fast-math?
189
214
case Intrinsic::expect: // From __builtin_expect.
190
- case Intrinsic::flt_rounds:
215
+ case Intrinsic::flt_rounds: // For FLT_ROUNDS macro from float.h.
216
+ // We do not have fesetround() in newlib, can we return a
217
+ // consistent rounding mode though?
191
218
case Intrinsic::log : // Rounding not defined: support with fast-math?
192
219
case Intrinsic::log2 : // Rounding not defined: support with fast-math?
193
220
case Intrinsic::log10 : // Rounding not defined: support with fast-math?
@@ -196,9 +223,9 @@ bool PNaClABIVerifyModule::IsWhitelistedIntrinsic(const Function* F,
196
223
case Intrinsic::powi: // Rounding not defined: support with fast-math?
197
224
case Intrinsic::prefetch: // Could ignore if target doesn't support?
198
225
case Intrinsic::sin : // Rounding not defined: support with fast-math?
199
- case Intrinsic::sqrt :
226
+ case Intrinsic::sqrt : // Rounding is defined, but setting errno up to libm.
200
227
case Intrinsic::stackrestore: // Used to support C99 VLAs.
201
- case Intrinsic::stacksave:
228
+ case Intrinsic::stacksave: // Used to support C99 VLAs.
202
229
// the *_with_overflow return struct types, so we'll need to fix these.
203
230
case Intrinsic::sadd_with_overflow: // Introduced by -ftrapv
204
231
case Intrinsic::ssub_with_overflow:
@@ -210,7 +237,7 @@ bool PNaClABIVerifyModule::IsWhitelistedIntrinsic(const Function* F,
210
237
}
211
238
}
212
239
213
- bool PNaClABIVerifyModule::IsWhitelistedMetadata (const NamedMDNode* MD) {
240
+ bool PNaClABIVerifyModule::isWhitelistedMetadata (const NamedMDNode * MD) {
214
241
return MD->getName ().startswith (" llvm.dbg." ) && PNaClABIAllowDebugMetadata;
215
242
}
216
243
@@ -234,7 +261,7 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
234
261
}
235
262
}
236
263
237
- CheckGlobalValueCommon (MI);
264
+ checkGlobalValueCommon (MI);
238
265
239
266
if (MI->isThreadLocal ()) {
240
267
Reporter->addError () << " Variable " << MI->getName () <<
@@ -252,7 +279,7 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
252
279
for (Module::const_iterator MI = M.begin (), ME = M.end (); MI != ME; ++MI) {
253
280
// Check intrinsics.
254
281
if (MI->isIntrinsic ()
255
- && !IsWhitelistedIntrinsic (MI, MI->getIntrinsicID ())) {
282
+ && !isWhitelistedIntrinsic (MI, MI->getIntrinsicID ())) {
256
283
Reporter->addError () << " Function " << MI->getName ()
257
284
<< " is a disallowed LLVM intrinsic\n " ;
258
285
}
@@ -279,7 +306,7 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
279
306
" is a variable-argument function (disallowed)\n " ;
280
307
}
281
308
282
- CheckGlobalValueCommon (MI);
309
+ checkGlobalValueCommon (MI);
283
310
284
311
if (MI->hasGC ()) {
285
312
Reporter->addError () << " Function " << MI->getName () <<
@@ -290,7 +317,7 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
290
317
// Check named metadata nodes
291
318
for (Module::const_named_metadata_iterator I = M.named_metadata_begin (),
292
319
E = M.named_metadata_end (); I != E; ++I) {
293
- if (!IsWhitelistedMetadata (I)) {
320
+ if (!isWhitelistedMetadata (I)) {
294
321
Reporter->addError () << " Named metadata node " << I->getName ()
295
322
<< " is disallowed\n " ;
296
323
} else {
0 commit comments