For PR411:

This patch is an incremental step towards supporting a flat symbol table.
It de-overloads the intrinsic functions by providing type-specific intrinsics
and arranging for automatically upgrading from the old overloaded name to
the new non-overloaded name. Specifically:
  llvm.isunordered -> llvm.isunordered.f32, llvm.isunordered.f64
  llvm.sqrt -> llvm.sqrt.f32, llvm.sqrt.f64
  llvm.ctpop -> llvm.ctpop.i8, llvm.ctpop.i16, llvm.ctpop.i32, llvm.ctpop.i64
  llvm.ctlz -> llvm.ctlz.i8, llvm.ctlz.i16, llvm.ctlz.i32, llvm.ctlz.i64
  llvm.cttz -> llvm.cttz.i8, llvm.cttz.i16, llvm.cttz.i32, llvm.cttz.i64
New code should not use the overloaded intrinsic names. Warnings will be
emitted if they are used.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25366 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2006-01-16 21:12:35 +00:00
parent e86bf519e1
commit 0b118206bf
12 changed files with 3319 additions and 2310 deletions

View File

@ -3394,20 +3394,21 @@ this can be specified as the fourth argument, otherwise it should be set to 0 or
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="i_isunordered">'<tt>llvm.isunordered</tt>' Intrinsic</a>
<a name="i_isunordered">'<tt>llvm.isunordered.*</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<pre>
declare bool %llvm.isunordered(&lt;float or double&gt; Val1, &lt;float or double&gt; Val2)
declare bool %llvm.isunordered.f32(float Val1, float Val2)
declare bool %llvm.isunordered.f64(double Val1, double Val2)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.isunordered</tt>' intrinsic returns true if either or both of the
The '<tt>llvm.isunordered</tt>' intrinsics return true if either or both of the
specified floating point values is a NAN.
</p>
@ -3435,13 +3436,14 @@ false.
<h5>Syntax:</h5>
<pre>
declare &lt;float or double&gt; %llvm.sqrt(&lt;float or double&gt; Val)
declare double %llvm.sqrt.f32(float Val)
declare double %llvm.sqrt.f64(double Val)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.sqrt</tt>' intrinsic returns the sqrt of the specified operand,
The '<tt>llvm.sqrt</tt>' intrinsics return the sqrt of the specified operand,
returning the same value as the libm '<tt>sqrt</tt>' function would. Unlike
<tt>sqrt</tt> in libm, however, <tt>llvm.sqrt</tt> has undefined behavior for
negative numbers (which allows for better optimization).
@ -3483,6 +3485,7 @@ These allow efficient code generation for some algorithms.
<h5>Syntax:</h5>
<pre>
declare ushort %llvm.bswap.i8( ubyte &lt;id&gt; )
declare ushort %llvm.bswap.i16( ushort &lt;id&gt; )
declare uint %llvm.bswap.i32( uint &lt;id&gt; )
declare ulong %llvm.bswap.i64( ulong &lt;id&gt; )
@ -3511,20 +3514,24 @@ to 64 bits.
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="int_ctpop">'<tt>llvm.ctpop</tt>' Intrinsic</a>
<a name="int_ctpop">'<tt>llvm.ctpop.*</tt>' Intrinsic</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<pre>
declare int %llvm.ctpop(int &lt;src&gt;)
declare sbyte %llvm.ctpop.i8(sbyte &lt;src&gt;)
declare short %llvm.ctpop.i16(short &lt;src&gt;)
declare int %llvm.ctpop.i32(int &lt;src&gt;)
declare long %llvm.ctpop.i64(long &lt;src&gt;)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.ctpop</tt>' intrinsic counts the number of ones in a variable.
The '<tt>llvm.ctpop</tt>' family of intrinsics counts the number of ones in a
variable.
</p>
<h5>Arguments:</h5>
@ -3550,15 +3557,17 @@ The '<tt>llvm.ctpop</tt>' intrinsic counts the 1's in a variable.
<h5>Syntax:</h5>
<pre>
declare int %llvm.ctlz(int &lt;src&gt;)
declare sbyte %llvm.ctlz.i8(sbyte &lt;src&gt;)
declare short %llvm.ctlz.i16(short &lt;src&gt;)
declare int %llvm.ctlz.i32(int &lt;src&gt;)
declare long %llvm.ctlz.i64(long &lt;src&gt;)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.ctlz</tt>' intrinsic counts the number of leading zeros in a
variable.
The '<tt>llvm.ctlz</tt>' family of intrinsic functions counts the number of
leading zeros in a variable.
</p>
<h5>Arguments:</h5>
@ -3588,13 +3597,17 @@ of src. For example, <tt>llvm.cttz(int 2) = 30</tt>.
<h5>Syntax:</h5>
<pre>
declare int %llvm.cttz(int &lt;src&gt;)
declare sbyte %llvm.cttz.i8(sbyte &lt;src&gt;)
declare short %llvm.cttz.i16(short &lt;src&gt;)
declare int %llvm.cttz.i32(int &lt;src&gt;)
declare long %llvm.cttz.i64(long &lt;src&gt;)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.cttz</tt>' intrinsic counts the number of trailing zeros.
The '<tt>llvm.cttz</tt>' family of intrinsic functions counts the number of
trailing zeros.
</p>
<h5>Arguments:</h5>

View File

@ -62,16 +62,27 @@ namespace Intrinsic {
memcpy, // Copy non-overlapping memory blocks
memmove, // Copy potentially overlapping memory blocks
memset, // Fill memory with a byte value
isunordered, // Return true if either argument is a NaN
sqrt, // Square root
isunordered_f32,// Return true if either float argument is a NaN
isunordered_f64,// Return true if either double argument is a NaN
sqrt_f32, // Square root of float
sqrt_f64, // Square root of double
// Bit manipulation instrinsics.
bswap_i16, // Byteswap 16 bits
bswap_i32, // Byteswap 32 bits
bswap_i64, // Byteswap 64 bits
ctpop, // Count population
ctlz, // Count leading zeros
cttz, // Count trailing zeros
ctpop_i8, // Count population of sbyte
ctpop_i16, // Count population of short
ctpop_i32, // Count population of int
ctpop_i64, // Count population of long
ctlz_i8, // Count leading zeros of sbyte
ctlz_i16, // Count leading zeros of short
ctlz_i32, // Count leading zeros of int
ctlz_i64, // Count leading zeros of long
cttz_i8, // Count trailing zeros of sbyte
cttz_i16, // Count trailing zeros of short
cttz_i32, // Count trailing zeros of int
cttz_i64, // Count trailing zeros of long
// Input/Output intrinsics.
readport,

View File

@ -35,15 +35,26 @@ llvm::canConstantFoldCallTo(Function *F) {
const std::string &Name = F->getName();
switch (F->getIntrinsicID()) {
case Intrinsic::isunordered:
case Intrinsic::sqrt:
case Intrinsic::isunordered_f32:
case Intrinsic::isunordered_f64:
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
case Intrinsic::bswap_i16:
case Intrinsic::bswap_i32:
case Intrinsic::bswap_i64:
// FIXME: these should be constant folded as well
//case Intrinsic::ctpop:
//case Intrinsic::ctlz:
//case Intrinsic::cttz:
//case Intrinsic::ctpop_i8:
//case Intrinsic::ctpop_i16:
//case Intrinsic::ctpop_i32:
//case Intrinsic::ctpop_i64:
//case Intrinsic::ctlz_i8:
//case Intrinsic::ctlz_i16:
//case Intrinsic::ctlz_i32:
//case Intrinsic::ctlz_i64:
//case Intrinsic::cttz_i8:
//case Intrinsic::cttz_i16:
//case Intrinsic::cttz_i32:
//case Intrinsic::cttz_i64:
return true;
default: break;
}
@ -125,7 +136,7 @@ llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
return ConstantFP::get(Ty, log(V));
else if (Name == "log10" && V > 0)
return ConstantFoldFP(log10, V, Ty);
else if (Name == "llvm.sqrt") {
else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") {
if (V >= -0.0)
return ConstantFP::get(Ty, sqrt(V));
else // Undefined
@ -164,7 +175,7 @@ llvm::ConstantFoldCall(Function *F, const std::vector<Constant*> &Operands) {
if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
double Op2V = Op2->getValue();
if (Name == "llvm.isunordered")
if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64")
return ConstantBool::get(IsNAN(Op1V) || IsNAN(Op2V));
else
if (Name == "pow") {

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,231 @@
typedef union {
/* A Bison parser, made by GNU Bison 1.875c. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
ESINT64VAL = 258,
EUINT64VAL = 259,
SINTVAL = 260,
UINTVAL = 261,
FPVAL = 262,
VOID = 263,
BOOL = 264,
SBYTE = 265,
UBYTE = 266,
SHORT = 267,
USHORT = 268,
INT = 269,
UINT = 270,
LONG = 271,
ULONG = 272,
FLOAT = 273,
DOUBLE = 274,
TYPE = 275,
LABEL = 276,
VAR_ID = 277,
LABELSTR = 278,
STRINGCONSTANT = 279,
IMPLEMENTATION = 280,
ZEROINITIALIZER = 281,
TRUETOK = 282,
FALSETOK = 283,
BEGINTOK = 284,
ENDTOK = 285,
DECLARE = 286,
GLOBAL = 287,
CONSTANT = 288,
SECTION = 289,
VOLATILE = 290,
TO = 291,
DOTDOTDOT = 292,
NULL_TOK = 293,
UNDEF = 294,
CONST = 295,
INTERNAL = 296,
LINKONCE = 297,
WEAK = 298,
APPENDING = 299,
OPAQUE = 300,
NOT = 301,
EXTERNAL = 302,
TARGET = 303,
TRIPLE = 304,
ENDIAN = 305,
POINTERSIZE = 306,
LITTLE = 307,
BIG = 308,
ALIGN = 309,
DEPLIBS = 310,
CALL = 311,
TAIL = 312,
CC_TOK = 313,
CCC_TOK = 314,
FASTCC_TOK = 315,
COLDCC_TOK = 316,
RET = 317,
BR = 318,
SWITCH = 319,
INVOKE = 320,
UNWIND = 321,
UNREACHABLE = 322,
ADD = 323,
SUB = 324,
MUL = 325,
DIV = 326,
REM = 327,
AND = 328,
OR = 329,
XOR = 330,
SETLE = 331,
SETGE = 332,
SETLT = 333,
SETGT = 334,
SETEQ = 335,
SETNE = 336,
MALLOC = 337,
ALLOCA = 338,
FREE = 339,
LOAD = 340,
STORE = 341,
GETELEMENTPTR = 342,
PHI_TOK = 343,
CAST = 344,
SELECT = 345,
SHL = 346,
SHR = 347,
VAARG = 348,
EXTRACTELEMENT = 349,
VAARG_old = 350,
VANEXT_old = 351
};
#endif
#define ESINT64VAL 258
#define EUINT64VAL 259
#define SINTVAL 260
#define UINTVAL 261
#define FPVAL 262
#define VOID 263
#define BOOL 264
#define SBYTE 265
#define UBYTE 266
#define SHORT 267
#define USHORT 268
#define INT 269
#define UINT 270
#define LONG 271
#define ULONG 272
#define FLOAT 273
#define DOUBLE 274
#define TYPE 275
#define LABEL 276
#define VAR_ID 277
#define LABELSTR 278
#define STRINGCONSTANT 279
#define IMPLEMENTATION 280
#define ZEROINITIALIZER 281
#define TRUETOK 282
#define FALSETOK 283
#define BEGINTOK 284
#define ENDTOK 285
#define DECLARE 286
#define GLOBAL 287
#define CONSTANT 288
#define SECTION 289
#define VOLATILE 290
#define TO 291
#define DOTDOTDOT 292
#define NULL_TOK 293
#define UNDEF 294
#define CONST 295
#define INTERNAL 296
#define LINKONCE 297
#define WEAK 298
#define APPENDING 299
#define OPAQUE 300
#define NOT 301
#define EXTERNAL 302
#define TARGET 303
#define TRIPLE 304
#define ENDIAN 305
#define POINTERSIZE 306
#define LITTLE 307
#define BIG 308
#define ALIGN 309
#define DEPLIBS 310
#define CALL 311
#define TAIL 312
#define CC_TOK 313
#define CCC_TOK 314
#define FASTCC_TOK 315
#define COLDCC_TOK 316
#define RET 317
#define BR 318
#define SWITCH 319
#define INVOKE 320
#define UNWIND 321
#define UNREACHABLE 322
#define ADD 323
#define SUB 324
#define MUL 325
#define DIV 326
#define REM 327
#define AND 328
#define OR 329
#define XOR 330
#define SETLE 331
#define SETGE 332
#define SETLT 333
#define SETGT 334
#define SETEQ 335
#define SETNE 336
#define MALLOC 337
#define ALLOCA 338
#define FREE 339
#define LOAD 340
#define STORE 341
#define GETELEMENTPTR 342
#define PHI_TOK 343
#define CAST 344
#define SELECT 345
#define SHL 346
#define SHR 347
#define VAARG 348
#define EXTRACTELEMENT 349
#define VAARG_old 350
#define VANEXT_old 351
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 878 "/proj/llvm/llvm2/lib/AsmParser/llvmAsmParser.y"
typedef union YYSTYPE {
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;
std::pair<llvm::PATypeHolder*, char*> *ArgVal;
@ -37,100 +264,14 @@ typedef union {
llvm::Instruction::OtherOps OtherOpVal;
llvm::Module::Endianness Endianness;
} YYSTYPE;
#define ESINT64VAL 257
#define EUINT64VAL 258
#define SINTVAL 259
#define UINTVAL 260
#define FPVAL 261
#define VOID 262
#define BOOL 263
#define SBYTE 264
#define UBYTE 265
#define SHORT 266
#define USHORT 267
#define INT 268
#define UINT 269
#define LONG 270
#define ULONG 271
#define FLOAT 272
#define DOUBLE 273
#define TYPE 274
#define LABEL 275
#define VAR_ID 276
#define LABELSTR 277
#define STRINGCONSTANT 278
#define IMPLEMENTATION 279
#define ZEROINITIALIZER 280
#define TRUETOK 281
#define FALSETOK 282
#define BEGINTOK 283
#define ENDTOK 284
#define DECLARE 285
#define GLOBAL 286
#define CONSTANT 287
#define SECTION 288
#define VOLATILE 289
#define TO 290
#define DOTDOTDOT 291
#define NULL_TOK 292
#define UNDEF 293
#define CONST 294
#define INTERNAL 295
#define LINKONCE 296
#define WEAK 297
#define APPENDING 298
#define OPAQUE 299
#define NOT 300
#define EXTERNAL 301
#define TARGET 302
#define TRIPLE 303
#define ENDIAN 304
#define POINTERSIZE 305
#define LITTLE 306
#define BIG 307
#define ALIGN 308
#define DEPLIBS 309
#define CALL 310
#define TAIL 311
#define CC_TOK 312
#define CCC_TOK 313
#define FASTCC_TOK 314
#define COLDCC_TOK 315
#define RET 316
#define BR 317
#define SWITCH 318
#define INVOKE 319
#define UNWIND 320
#define UNREACHABLE 321
#define ADD 322
#define SUB 323
#define MUL 324
#define DIV 325
#define REM 326
#define AND 327
#define OR 328
#define XOR 329
#define SETLE 330
#define SETGE 331
#define SETLT 332
#define SETGT 333
#define SETEQ 334
#define SETNE 335
#define MALLOC 336
#define ALLOCA 337
#define FREE 338
#define LOAD 339
#define STORE 340
#define GETELEMENTPTR 341
#define PHI_TOK 342
#define CAST 343
#define SELECT 344
#define SHL 345
#define SHR 346
#define VAARG 347
#define EXTRACTELEMENT 348
#define VAARG_old 349
#define VANEXT_old 350
/* Line 1275 of yacc.c. */
#line 269 "llvmAsmParser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE llvmAsmlval;

View File

@ -17,6 +17,7 @@
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/Assembly/AutoUpgrade.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
@ -104,12 +105,16 @@ static struct PerModuleInfo {
ThrowException(UndefinedReferences);
}
// Rename any overloaded intrinsic functions.
for (Module::iterator FI = CurrentModule->begin(), FE =
CurrentModule->end(); FI != FE; ++FI)
UpgradeIntrinsicFunction(&(*FI));
Values.clear(); // Clear out function local definitions
Types.clear();
CurrentModule = 0;
}
// GetForwardRefForGlobal - Check to see if there is a forward reference
// for this global. If so, remove it from the GlobalRefs map and return it.
// If not, just return null.

View File

@ -17,6 +17,7 @@
//===----------------------------------------------------------------------===//
#include "Reader.h"
#include "llvm/Assembly/AutoUpgrade.h"
#include "llvm/Bytecode/BytecodeHandler.h"
#include "llvm/BasicBlock.h"
#include "llvm/CallingConv.h"
@ -2002,6 +2003,7 @@ void BytecodeReader::ParseModuleGlobalInfo() {
// Insert the place holder.
Function *Func = new Function(FTy, GlobalValue::ExternalLinkage,
"", TheModule);
UpgradeIntrinsicFunction(Func);
insertValue(Func, (FnSignature & (~0U >> 1)) >> 5, ModuleValues);
// Flags are not used yet.

View File

@ -113,11 +113,13 @@ void DefaultIntrinsicLowering::AddPrototypes(Module &M) {
Type::IntTy, (--(--I->arg_end()))->getType(),
(Type *)0);
break;
case Intrinsic::isunordered:
case Intrinsic::isunordered_f32:
case Intrinsic::isunordered_f64:
EnsureFunctionExists(M, "isunordered", I->arg_begin(), I->arg_end(),
Type::BoolTy);
break;
case Intrinsic::sqrt:
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
if(I->arg_begin()->getType() == Type::FloatTy)
EnsureFunctionExists(M, "sqrtf", I->arg_begin(), I->arg_end(),
Type::FloatTy);
@ -326,22 +328,30 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
AbortFCache);
break;
}
case Intrinsic::ctpop_i8:
case Intrinsic::ctpop_i16:
case Intrinsic::ctpop_i32:
case Intrinsic::ctpop_i64:
CI->replaceAllUsesWith(LowerCTPOP(CI->getOperand(1), CI));
break;
case Intrinsic::bswap_i16:
case Intrinsic::bswap_i32:
case Intrinsic::bswap_i64:
CI->replaceAllUsesWith(LowerBSWAP(CI->getOperand(1), CI));
break;
case Intrinsic::ctpop:
CI->replaceAllUsesWith(LowerCTPOP(CI->getOperand(1), CI));
break;
case Intrinsic::ctlz:
case Intrinsic::ctlz_i8:
case Intrinsic::ctlz_i16:
case Intrinsic::ctlz_i32:
case Intrinsic::ctlz_i64:
CI->replaceAllUsesWith(LowerCTLZ(CI->getOperand(1), CI));
break;
case Intrinsic::cttz: {
case Intrinsic::cttz_i8:
case Intrinsic::cttz_i16:
case Intrinsic::cttz_i32:
case Intrinsic::cttz_i64: {
// cttz(x) -> ctpop(~X & (X-1))
Value *Src = CI->getOperand(1);
Value *NotSrc = BinaryOperator::createNot(Src, Src->getName()+".not", CI);
@ -419,7 +429,8 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
(*(CI->op_begin()+1))->getType(), MemsetFCache);
break;
}
case Intrinsic::isunordered: {
case Intrinsic::isunordered_f32:
case Intrinsic::isunordered_f64: {
Value *L = CI->getOperand(1);
Value *R = CI->getOperand(2);
@ -430,7 +441,8 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
"isunordered", CI));
break;
}
case Intrinsic::sqrt: {
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64: {
static Function *sqrtFCache = 0;
static Function *sqrtfFCache = 0;
if(CI->getType() == Type::FloatTy)

View File

@ -963,12 +963,14 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
setValue(&I, DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType())));
return 0;
case Intrinsic::isunordered:
case Intrinsic::isunordered_f32:
case Intrinsic::isunordered_f64:
setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)),
getValue(I.getOperand(2)), ISD::SETUO));
return 0;
case Intrinsic::sqrt:
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
setValue(&I, DAG.getNode(ISD::FSQRT,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
@ -996,17 +998,26 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::cttz:
case Intrinsic::cttz_i8:
case Intrinsic::cttz_i16:
case Intrinsic::cttz_i32:
case Intrinsic::cttz_i64:
setValue(&I, DAG.getNode(ISD::CTTZ,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::ctlz:
case Intrinsic::ctlz_i8:
case Intrinsic::ctlz_i16:
case Intrinsic::ctlz_i32:
case Intrinsic::ctlz_i64:
setValue(&I, DAG.getNode(ISD::CTLZ,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
case Intrinsic::ctpop:
case Intrinsic::ctpop_i8:
case Intrinsic::ctpop_i16:
case Intrinsic::ctpop_i32:
case Intrinsic::ctpop_i64:
setValue(&I, DAG.getNode(ISD::CTPOP,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));

View File

@ -297,14 +297,25 @@ bool llvm::isInstructionTriviallyDead(Instruction *I) {
case Intrinsic::returnaddress:
case Intrinsic::frameaddress:
case Intrinsic::stacksave:
case Intrinsic::isunordered:
case Intrinsic::isunordered_f32:
case Intrinsic::isunordered_f64:
case Intrinsic::bswap_i16:
case Intrinsic::bswap_i32:
case Intrinsic::bswap_i64:
case Intrinsic::ctpop:
case Intrinsic::ctlz:
case Intrinsic::cttz:
case Intrinsic::sqrt:
case Intrinsic::ctpop_i8:
case Intrinsic::ctpop_i16:
case Intrinsic::ctpop_i32:
case Intrinsic::ctpop_i64:
case Intrinsic::ctlz_i8:
case Intrinsic::ctlz_i16:
case Intrinsic::ctlz_i32:
case Intrinsic::ctlz_i64:
case Intrinsic::cttz_i8:
case Intrinsic::cttz_i16:
case Intrinsic::cttz_i32:
case Intrinsic::cttz_i64:
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
return true; // These intrinsics have no side effects.
}
return false;

View File

@ -200,79 +200,93 @@ void Function::dropAllReferences() {
/// llvm/Intrinsics.h.
///
unsigned Function::getIntrinsicID() const {
if (getName().size() < 5 || getName()[4] != '.' || getName()[0] != 'l' ||
getName()[1] != 'l' || getName()[2] != 'v' || getName()[3] != 'm')
const std::string& Name = this->getName();
if (Name.size() < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l'
|| Name[2] != 'v' || Name[3] != 'm')
return 0; // All intrinsics start with 'llvm.'
assert(getName().size() != 5 && "'llvm.' is an invalid intrinsic name!");
assert(Name.size() != 5 && "'llvm.' is an invalid intrinsic name!");
switch (getName()[5]) {
switch (Name[5]) {
case 'b':
if (getName() == "llvm.bswap.i16") return Intrinsic::bswap_i16;
if (getName() == "llvm.bswap.i32") return Intrinsic::bswap_i32;
if (getName() == "llvm.bswap.i64") return Intrinsic::bswap_i64;
if (Name == "llvm.bswap.i16") return Intrinsic::bswap_i16;
if (Name == "llvm.bswap.i32") return Intrinsic::bswap_i32;
if (Name == "llvm.bswap.i64") return Intrinsic::bswap_i64;
break;
case 'c':
if (getName() == "llvm.ctpop") return Intrinsic::ctpop;
if (getName() == "llvm.cttz") return Intrinsic::cttz;
if (getName() == "llvm.ctlz") return Intrinsic::ctlz;
if (Name == "llvm.ctpop.i8") return Intrinsic::ctpop_i8;
if (Name == "llvm.ctpop.i16") return Intrinsic::ctpop_i16;
if (Name == "llvm.ctpop.i32") return Intrinsic::ctpop_i32;
if (Name == "llvm.ctpop.i64") return Intrinsic::ctpop_i64;
if (Name == "llvm.cttz.i8") return Intrinsic::cttz_i8;
if (Name == "llvm.cttz.i16") return Intrinsic::cttz_i16;
if (Name == "llvm.cttz.i32") return Intrinsic::cttz_i32;
if (Name == "llvm.cttz.i64") return Intrinsic::cttz_i64;
if (Name == "llvm.ctlz.i8") return Intrinsic::ctlz_i8;
if (Name == "llvm.ctlz.i16") return Intrinsic::ctlz_i16;
if (Name == "llvm.ctlz.i32") return Intrinsic::ctlz_i32;
if (Name == "llvm.ctlz.i64") return Intrinsic::ctlz_i64;
break;
case 'd':
if (getName() == "llvm.dbg.stoppoint") return Intrinsic::dbg_stoppoint;
if (getName() == "llvm.dbg.region.start")return Intrinsic::dbg_region_start;
if (getName() == "llvm.dbg.region.end") return Intrinsic::dbg_region_end;
if (getName() == "llvm.dbg.func.start") return Intrinsic::dbg_func_start;
if (getName() == "llvm.dbg.declare") return Intrinsic::dbg_declare;
if (Name == "llvm.dbg.stoppoint") return Intrinsic::dbg_stoppoint;
if (Name == "llvm.dbg.region.start")return Intrinsic::dbg_region_start;
if (Name == "llvm.dbg.region.end") return Intrinsic::dbg_region_end;
if (Name == "llvm.dbg.func.start") return Intrinsic::dbg_func_start;
if (Name == "llvm.dbg.declare") return Intrinsic::dbg_declare;
break;
case 'f':
if (getName() == "llvm.frameaddress") return Intrinsic::frameaddress;
if (Name == "llvm.frameaddress") return Intrinsic::frameaddress;
break;
case 'g':
if (getName() == "llvm.gcwrite") return Intrinsic::gcwrite;
if (getName() == "llvm.gcread") return Intrinsic::gcread;
if (getName() == "llvm.gcroot") return Intrinsic::gcroot;
if (Name == "llvm.gcwrite") return Intrinsic::gcwrite;
if (Name == "llvm.gcread") return Intrinsic::gcread;
if (Name == "llvm.gcroot") return Intrinsic::gcroot;
break;
case 'i':
if (getName() == "llvm.isunordered") return Intrinsic::isunordered;
if (Name == "llvm.isunordered.f32")
return Intrinsic::isunordered_f32;
if (Name == "llvm.isunordered.f64")
return Intrinsic::isunordered_f64;
break;
case 'l':
if (getName() == "llvm.longjmp") return Intrinsic::longjmp;
if (Name == "llvm.longjmp") return Intrinsic::longjmp;
break;
case 'm':
if (getName() == "llvm.memcpy") return Intrinsic::memcpy;
if (getName() == "llvm.memmove") return Intrinsic::memmove;
if (getName() == "llvm.memset") return Intrinsic::memset;
if (Name == "llvm.memcpy") return Intrinsic::memcpy;
if (Name == "llvm.memmove") return Intrinsic::memmove;
if (Name == "llvm.memset") return Intrinsic::memset;
break;
case 'p':
if (getName() == "llvm.prefetch") return Intrinsic::prefetch;
if (getName() == "llvm.pcmarker") return Intrinsic::pcmarker;
if (Name == "llvm.prefetch") return Intrinsic::prefetch;
if (Name == "llvm.pcmarker") return Intrinsic::pcmarker;
break;
case 'r':
if (getName() == "llvm.returnaddress") return Intrinsic::returnaddress;
if (getName() == "llvm.readport") return Intrinsic::readport;
if (getName() == "llvm.readio") return Intrinsic::readio;
if (getName() == "llvm.readcyclecounter") return Intrinsic::readcyclecounter;
if (Name == "llvm.returnaddress") return Intrinsic::returnaddress;
if (Name == "llvm.readport") return Intrinsic::readport;
if (Name == "llvm.readio") return Intrinsic::readio;
if (Name == "llvm.readcyclecounter") return Intrinsic::readcyclecounter;
break;
case 's':
if (getName() == "llvm.setjmp") return Intrinsic::setjmp;
if (getName() == "llvm.sigsetjmp") return Intrinsic::sigsetjmp;
if (getName() == "llvm.siglongjmp") return Intrinsic::siglongjmp;
if (getName() == "llvm.stackrestore") return Intrinsic::stackrestore;
if (getName() == "llvm.stacksave") return Intrinsic::stacksave;
if (getName() == "llvm.sqrt") return Intrinsic::sqrt;
if (Name == "llvm.setjmp") return Intrinsic::setjmp;
if (Name == "llvm.sigsetjmp") return Intrinsic::sigsetjmp;
if (Name == "llvm.siglongjmp") return Intrinsic::siglongjmp;
if (Name == "llvm.stackrestore") return Intrinsic::stackrestore;
if (Name == "llvm.stacksave") return Intrinsic::stacksave;
if (Name == "llvm.sqrt.f32") return Intrinsic::sqrt_f32;
if (Name == "llvm.sqrt.f64") return Intrinsic::sqrt_f64;
break;
case 'v':
if (getName() == "llvm.va_copy") return Intrinsic::vacopy;
if (getName() == "llvm.va_end") return Intrinsic::vaend;
if (getName() == "llvm.va_start") return Intrinsic::vastart;
if (Name == "llvm.va_copy") return Intrinsic::vacopy;
if (Name == "llvm.va_end") return Intrinsic::vaend;
if (Name == "llvm.va_start") return Intrinsic::vastart;
break;
case 'w':
if (getName() == "llvm.writeport") return Intrinsic::writeport;
if (getName() == "llvm.writeio") return Intrinsic::writeio;
if (Name == "llvm.writeport") return Intrinsic::writeport;
if (Name == "llvm.writeio") return Intrinsic::writeio;
break;
}
// The "llvm." namespace is reserved!
assert(0 && "Unknown LLVM intrinsic function!");
assert(!"Unknown LLVM intrinsic function!");
return 0;
}

View File

@ -128,7 +128,8 @@ namespace { // Anonymous namespace for class
if (I->isExternal()) visitFunction(*I);
}
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I)
visitGlobalVariable(*I);
// If the module is broken, abort at this time.
@ -729,15 +730,27 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
break;
}
case Intrinsic::isunordered:
case Intrinsic::isunordered_f32:
Assert1(FT->getNumParams() == 2,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == Type::BoolTy,
"Return type is not bool!", IF);
Assert1(FT->getParamType(0) == FT->getParamType(1),
"Arguments must be of the same type!", IF);
Assert1(FT->getParamType(0)->isFloatingPoint(),
"Argument is not a floating point type!", IF);
Assert1(FT->getParamType(0) == Type::FloatTy,
"Arguments must be a 32-bit floating point type!", IF);
NumArgs = 2;
break;
case Intrinsic::isunordered_f64:
Assert1(FT->getNumParams() == 2,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == Type::BoolTy,
"Return type is not bool!", IF);
Assert1(FT->getParamType(0) == FT->getParamType(1),
"Arguments must be of the same type!", IF);
Assert1(FT->getParamType(0) == Type::DoubleTy,
"Argument is not a 64-bit floating point type!", IF);
NumArgs = 2;
break;
@ -779,23 +792,147 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
NumArgs = 1;
break;
case Intrinsic::ctpop:
case Intrinsic::ctlz:
case Intrinsic::cttz:
case Intrinsic::ctpop_i8:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0)->isIntegral(),
"Argument must be of an int type!", IF);
Assert1(FT->getParamType(0) == Type::UByteTy
|| FT->getParamType(0) == Type::SByteTy,
"Argument must be a byte type!", IF);
NumArgs = 1;
break;
case Intrinsic::sqrt:
case Intrinsic::ctpop_i16:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getParamType(0)->isFloatingPoint(),
"Argument is not a floating point type!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UShortTy
|| FT->getParamType(0) == Type::ShortTy,
"Argument must be a short type!", IF);
NumArgs = 1;
break;
case Intrinsic::ctpop_i32:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UIntTy
|| FT->getParamType(0) == Type::IntTy,
"Argument must be an int type!", IF);
NumArgs = 1;
break;
case Intrinsic::ctpop_i64:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::ULongTy
|| FT->getParamType(0) == Type::LongTy,
"Argument must be a long type!", IF);
NumArgs = 1;
break;
case Intrinsic::ctlz_i8:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UByteTy
|| FT->getParamType(0) == Type::SByteTy,
"Argument must be a byte type!", IF);
NumArgs = 1;
break;
case Intrinsic::ctlz_i16:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UShortTy
|| FT->getParamType(0) == Type::ShortTy,
"Argument must be a short type!", IF);
NumArgs = 1;
break;
case Intrinsic::ctlz_i32:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UIntTy
|| FT->getParamType(0) == Type::IntTy,
"Argument must be an int type!", IF);
NumArgs = 1;
break;
case Intrinsic::ctlz_i64:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::ULongTy
|| FT->getParamType(0) == Type::LongTy,
"Argument must be a long type!", IF);
NumArgs = 1;
break;
case Intrinsic::cttz_i8:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UByteTy
|| FT->getParamType(0) == Type::SByteTy,
"Argument must be a byte type!", IF);
NumArgs = 1;
break;
case Intrinsic::cttz_i16:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UShortTy
|| FT->getParamType(0) == Type::ShortTy,
"Argument must be a short type!", IF);
NumArgs = 1;
break;
case Intrinsic::cttz_i32:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::UIntTy
|| FT->getParamType(0) == Type::IntTy,
"Argument must be an int type!", IF);
NumArgs = 1;
break;
case Intrinsic::cttz_i64:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type does not match source type", IF);
Assert1(FT->getParamType(0) == Type::ULongTy
|| FT->getParamType(0) == Type::LongTy,
"Argument must be a long type!", IF);
NumArgs = 1;
break;
case Intrinsic::sqrt_f32:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getParamType(0) == Type::FloatTy,
"Argument is not a 32-bit floating point type!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type is not the same as argument type!", IF);
NumArgs = 1;
break;
case Intrinsic::sqrt_f64:
Assert1(FT->getNumParams() == 1,
"Illegal # arguments for intrinsic function!", IF);
Assert1(FT->getParamType(0) == Type::DoubleTy,
"Argument is not a 64-bit floating point type!", IF);
Assert1(FT->getReturnType() == FT->getParamType(0),
"Return type is not the same as argument type!", IF);
NumArgs = 1;