mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
For PR950:
This patch converts the old SHR instruction into two instructions, AShr (Arithmetic) and LShr (Logical). The Shr instructions now are not dependent on the sign of their operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31542 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
73fb07566b
commit
3822ff5c71
@ -92,7 +92,8 @@
|
||||
<li><a href="#i_or">'<tt>or</tt>' Instruction</a></li>
|
||||
<li><a href="#i_xor">'<tt>xor</tt>' Instruction</a></li>
|
||||
<li><a href="#i_shl">'<tt>shl</tt>' Instruction</a></li>
|
||||
<li><a href="#i_shr">'<tt>shr</tt>' Instruction</a></li>
|
||||
<li><a href="#i_lshr">'<tt>lshr</tt>' Instruction</a></li>
|
||||
<li><a href="#i_ashr">'<tt>ashr</tt>' Instruction</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#vectorops">Vector Operations</a>
|
||||
@ -2070,30 +2071,64 @@ type.</p>
|
||||
</pre>
|
||||
</div>
|
||||
<!-- _______________________________________________________________________ -->
|
||||
<div class="doc_subsubsection"> <a name="i_shr">'<tt>shr</tt>'
|
||||
<div class="doc_subsubsection"> <a name="i_lshr">'<tt>lshr</tt>'
|
||||
Instruction</a> </div>
|
||||
<div class="doc_text">
|
||||
<h5>Syntax:</h5>
|
||||
<pre> <result> = shr <ty> <var1>, ubyte <var2> <i>; yields {ty}:result</i>
|
||||
<pre> <result> = lshr <ty> <var1>, ubyte <var2> <i>; yields {ty}:result</i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>shr</tt>' instruction returns the first operand shifted to
|
||||
the right a specified number of bits.</p>
|
||||
<p>The '<tt>lshr</tt>' instruction (logical shift right) returns the first
|
||||
operand shifted to the right a specified number of bits.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The first argument to the '<tt>shr</tt>' instruction must be an <a
|
||||
href="#t_integer">integer</a> type. The second argument must be an '<tt>ubyte</tt>'
|
||||
type.</p>
|
||||
<p>The first argument to the '<tt>lshr</tt>' instruction must be an <a
|
||||
href="#t_integer">integer</a> type. The second argument must be an '<tt>ubyte</tt>' type.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>If the first argument is a <a href="#t_signed">signed</a> type, the
|
||||
most significant bit is duplicated in the newly free'd bit positions.
|
||||
If the first argument is unsigned, zero bits shall fill the empty
|
||||
positions.</p>
|
||||
<p>This instruction always performs a logical shift right operation, regardless
|
||||
of whether the arguments are unsigned or not. The <tt>var2</tt> most significant
|
||||
bits will be filled with zero bits after the shift.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre> <result> = shr int 4, ubyte %var <i>; yields {int}:result = 4 >> %var</i>
|
||||
<result> = shr uint 4, ubyte 1 <i>; yields {uint}:result = 2</i>
|
||||
<result> = shr int 4, ubyte 2 <i>; yields {int}:result = 1</i>
|
||||
<result> = shr sbyte 4, ubyte 3 <i>; yields {sbyte}:result = 0</i>
|
||||
<result> = shr sbyte -2, ubyte 1 <i>; yields {sbyte}:result = -1</i>
|
||||
<pre>
|
||||
<result> = lshr uint 4, ubyte 1 <i>; yields {uint}:result = 2</i>
|
||||
<result> = lshr int 4, ubyte 2 <i>; yields {uint}:result = 1</i>
|
||||
<result> = lshr sbyte 4, ubyte 3 <i>; yields {sbyte}:result = 0</i>
|
||||
<result> = lshr sbyte -2, ubyte 1 <i>; yields {sbyte}:result = 0x7FFFFFFF </i>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection"> <a name="i_ashr">'<tt>ashr</tt>'
|
||||
Instruction</a> </div>
|
||||
<div class="doc_text">
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<pre> <result> = ashr <ty> <var1>, ubyte <var2> <i>; yields {ty}:result</i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
<p>The '<tt>ashr</tt>' instruction (arithmetic shift right) returns the first
|
||||
operand shifted to the right a specified number of bits.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The first argument to the '<tt>ashr</tt>' instruction must be an
|
||||
<a href="#t_integer">integer</a> type. The second argument must be an
|
||||
'<tt>ubyte</tt>' type.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>This instruction always performs an arithmetic shift right operation,
|
||||
regardless of whether the arguments are signed or not. The <tt>var2</tt> most
|
||||
significant bits will be filled with the sign bit of <tt>var1</tt>.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
<result> = ashr uint 4, ubyte 1 <i>; yields {uint}:result = 2</i>
|
||||
<result> = ashr int 4, ubyte 2 <i>; yields {int}:result = 1</i>
|
||||
<result> = ashr ubyte 4, ubyte 3 <i>; yields {ubyte}:result = 0</i>
|
||||
<result> = ashr sbyte -2, ubyte 1 <i>; yields {sbyte}:result = -1</i>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
@ -564,10 +564,8 @@ public:
|
||||
static Constant *getSetLE(Constant *C1, Constant *C2);
|
||||
static Constant *getSetGE(Constant *C1, Constant *C2);
|
||||
static Constant *getShl(Constant *C1, Constant *C2);
|
||||
static Constant *getShr(Constant *C1, Constant *C2);
|
||||
|
||||
static Constant *getUShr(Constant *C1, Constant *C2); // unsigned shr
|
||||
static Constant *getSShr(Constant *C1, Constant *C2); // signed shr
|
||||
static Constant *getLShr(Constant *C1, Constant *C2);
|
||||
static Constant *getAShr(Constant *C1, Constant *C2);
|
||||
|
||||
/// Getelementptr form. std::vector<Value*> is only accepted for convenience:
|
||||
/// all elements must be Constant's.
|
||||
|
@ -15,8 +15,8 @@
|
||||
|
||||
// NOTE: NO INCLUDE GUARD DESIRED!
|
||||
|
||||
// Provide definitions of macros so that users of this file do not have to define
|
||||
// everything to use it...
|
||||
// Provide definitions of macros so that users of this file do not have to
|
||||
// define everything to use it...
|
||||
//
|
||||
#ifndef FIRST_TERM_INST
|
||||
#define FIRST_TERM_INST(num)
|
||||
@ -129,16 +129,17 @@ HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
|
||||
HANDLE_OTHER_INST(31, PHI , PHINode ) // PHI node instruction
|
||||
HANDLE_OTHER_INST(32, Cast , CastInst ) // Type cast
|
||||
HANDLE_OTHER_INST(33, Call , CallInst ) // Call a function
|
||||
HANDLE_OTHER_INST(34, Shl , ShiftInst ) // Shift operations
|
||||
HANDLE_OTHER_INST(35, Shr , ShiftInst )
|
||||
HANDLE_OTHER_INST(36, Select , SelectInst ) // select instruction
|
||||
HANDLE_OTHER_INST(37, UserOp1, Instruction) // May be used internally in a pass
|
||||
HANDLE_OTHER_INST(38, UserOp2, Instruction)
|
||||
HANDLE_OTHER_INST(39, VAArg , VAArgInst ) // vaarg instruction
|
||||
HANDLE_OTHER_INST(40, ExtractElement, ExtractElementInst)// extract from vector.
|
||||
HANDLE_OTHER_INST(41, InsertElement, InsertElementInst) // insert into vector
|
||||
HANDLE_OTHER_INST(42, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
||||
LAST_OTHER_INST(42)
|
||||
HANDLE_OTHER_INST(34, Shl , ShiftInst ) // Shift Left operations (logical)
|
||||
HANDLE_OTHER_INST(35, LShr , ShiftInst ) // Logical Shift right (unsigned)
|
||||
HANDLE_OTHER_INST(36, AShr , ShiftInst ) // Arithmetic shift right (signed)
|
||||
HANDLE_OTHER_INST(37, Select , SelectInst ) // select instruction
|
||||
HANDLE_OTHER_INST(38, UserOp1, Instruction) // May be used internally in a pass
|
||||
HANDLE_OTHER_INST(39, UserOp2, Instruction) // Internal to passes only
|
||||
HANDLE_OTHER_INST(40, VAArg , VAArgInst ) // vaarg instruction
|
||||
HANDLE_OTHER_INST(41, ExtractElement, ExtractElementInst)// extract from vector.
|
||||
HANDLE_OTHER_INST(42, InsertElement, InsertElementInst) // insert into vector
|
||||
HANDLE_OTHER_INST(43, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
|
||||
LAST_OTHER_INST(43)
|
||||
|
||||
#undef FIRST_TERM_INST
|
||||
#undef HANDLE_TERM_INST
|
||||
|
@ -604,7 +604,8 @@ class ShiftInst : public Instruction {
|
||||
Ops[1].init(SI.Ops[1], this);
|
||||
}
|
||||
void init(OtherOps Opcode, Value *S, Value *SA) {
|
||||
assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
|
||||
assert((Opcode == Shl || Opcode == LShr || Opcode == AShr) &&
|
||||
"ShiftInst Opcode invalid!");
|
||||
Ops[0].init(S, this);
|
||||
Ops[1].init(SA, this);
|
||||
}
|
||||
@ -638,7 +639,11 @@ public:
|
||||
|
||||
/// isLogicalShift - Return true if this is a logical shift left or a logical
|
||||
/// shift right.
|
||||
bool isLogicalShift() const;
|
||||
bool isLogicalShift() const {
|
||||
unsigned opcode = getOpcode();
|
||||
return opcode == Instruction::Shl || opcode == Instruction::LShr;
|
||||
}
|
||||
|
||||
|
||||
/// isArithmeticShift - Return true if this is a sign-extending shift right
|
||||
/// operation.
|
||||
@ -652,7 +657,8 @@ public:
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const ShiftInst *) { return true; }
|
||||
static inline bool classof(const Instruction *I) {
|
||||
return (I->getOpcode() == Instruction::Shr) |
|
||||
return (I->getOpcode() == Instruction::LShr) |
|
||||
(I->getOpcode() == Instruction::AShr) |
|
||||
(I->getOpcode() == Instruction::Shl);
|
||||
}
|
||||
static inline bool classof(const Value *V) {
|
||||
|
@ -172,9 +172,49 @@ inline BinaryOp_match<LHS, RHS, Instruction::Shl,
|
||||
}
|
||||
|
||||
template<typename LHS, typename RHS>
|
||||
inline BinaryOp_match<LHS, RHS, Instruction::Shr,
|
||||
ShiftInst> m_Shr(const LHS &L, const RHS &R) {
|
||||
return BinaryOp_match<LHS, RHS, Instruction::Shr, ShiftInst>(L, R);
|
||||
inline BinaryOp_match<LHS, RHS, Instruction::LShr,
|
||||
ShiftInst> m_LShr(const LHS &L, const RHS &R) {
|
||||
return BinaryOp_match<LHS, RHS, Instruction::LShr, ShiftInst>(L, R);
|
||||
}
|
||||
|
||||
template<typename LHS, typename RHS>
|
||||
inline BinaryOp_match<LHS, RHS, Instruction::AShr,
|
||||
ShiftInst> m_AShr(const LHS &L, const RHS &R) {
|
||||
return BinaryOp_match<LHS, RHS, Instruction::AShr, ShiftInst>(L, R);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Matchers for either AShr or LShr .. for convenience
|
||||
//
|
||||
template<typename LHS_t, typename RHS_t, typename ConcreteTy = ShiftInst>
|
||||
struct Shr_match {
|
||||
LHS_t L;
|
||||
RHS_t R;
|
||||
|
||||
Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
|
||||
|
||||
template<typename OpTy>
|
||||
bool match(OpTy *V) {
|
||||
if (V->getValueType() == Value::InstructionVal + Instruction::LShr ||
|
||||
V->getValueType() == Value::InstructionVal + Instruction::AShr) {
|
||||
ConcreteTy *I = cast<ConcreteTy>(V);
|
||||
return (I->getOpcode() == Instruction::AShr ||
|
||||
I->getOpcode() == Instruction::LShr) &&
|
||||
L.match(I->getOperand(0)) &&
|
||||
R.match(I->getOperand(1));
|
||||
}
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
|
||||
return (CE->getOpcode() == Instruction::LShr ||
|
||||
CE->getOpcode() == Instruction::AShr) &&
|
||||
L.match(CE->getOperand(0)) &&
|
||||
R.match(CE->getOperand(1));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LHS, typename RHS>
|
||||
inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
|
||||
return Shr_match<LHS, RHS>(L, R);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -784,7 +784,8 @@ void Andersens::visitInstruction(Instruction &I) {
|
||||
case Instruction::Unreachable:
|
||||
case Instruction::Free:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
return;
|
||||
default:
|
||||
// Is this something we aren't handling yet?
|
||||
|
@ -280,7 +280,9 @@ call { RET_TOK(OtherOpVal, Call, CALL); }
|
||||
cast { RET_TOK(OtherOpVal, Cast, CAST); }
|
||||
select { RET_TOK(OtherOpVal, Select, SELECT); }
|
||||
shl { RET_TOK(OtherOpVal, Shl, SHL); }
|
||||
shr { RET_TOK(OtherOpVal, Shr, SHR); }
|
||||
shr { RET_TOK_OBSOLETE(OtherOpVal, LShr, LSHR); }
|
||||
lshr { RET_TOK(OtherOpVal, LShr, LSHR); }
|
||||
ashr { RET_TOK(OtherOpVal, AShr, ASHR); }
|
||||
vanext { return VANEXT_old; }
|
||||
vaarg { return VAARG_old; }
|
||||
va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,266 @@
|
||||
typedef union {
|
||||
/* A Bison parser, made by GNU Bison 2.1. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, 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,
|
||||
DLLIMPORT = 300,
|
||||
DLLEXPORT = 301,
|
||||
EXTERN_WEAK = 302,
|
||||
OPAQUE = 303,
|
||||
NOT = 304,
|
||||
EXTERNAL = 305,
|
||||
TARGET = 306,
|
||||
TRIPLE = 307,
|
||||
ENDIAN = 308,
|
||||
POINTERSIZE = 309,
|
||||
LITTLE = 310,
|
||||
BIG = 311,
|
||||
ALIGN = 312,
|
||||
DEPLIBS = 313,
|
||||
CALL = 314,
|
||||
TAIL = 315,
|
||||
ASM_TOK = 316,
|
||||
MODULE = 317,
|
||||
SIDEEFFECT = 318,
|
||||
CC_TOK = 319,
|
||||
CCC_TOK = 320,
|
||||
CSRETCC_TOK = 321,
|
||||
FASTCC_TOK = 322,
|
||||
COLDCC_TOK = 323,
|
||||
X86_STDCALLCC_TOK = 324,
|
||||
X86_FASTCALLCC_TOK = 325,
|
||||
DATALAYOUT = 326,
|
||||
RET = 327,
|
||||
BR = 328,
|
||||
SWITCH = 329,
|
||||
INVOKE = 330,
|
||||
UNWIND = 331,
|
||||
UNREACHABLE = 332,
|
||||
ADD = 333,
|
||||
SUB = 334,
|
||||
MUL = 335,
|
||||
UDIV = 336,
|
||||
SDIV = 337,
|
||||
FDIV = 338,
|
||||
UREM = 339,
|
||||
SREM = 340,
|
||||
FREM = 341,
|
||||
AND = 342,
|
||||
OR = 343,
|
||||
XOR = 344,
|
||||
SETLE = 345,
|
||||
SETGE = 346,
|
||||
SETLT = 347,
|
||||
SETGT = 348,
|
||||
SETEQ = 349,
|
||||
SETNE = 350,
|
||||
MALLOC = 351,
|
||||
ALLOCA = 352,
|
||||
FREE = 353,
|
||||
LOAD = 354,
|
||||
STORE = 355,
|
||||
GETELEMENTPTR = 356,
|
||||
PHI_TOK = 357,
|
||||
CAST = 358,
|
||||
SELECT = 359,
|
||||
SHL = 360,
|
||||
LSHR = 361,
|
||||
ASHR = 362,
|
||||
VAARG = 363,
|
||||
EXTRACTELEMENT = 364,
|
||||
INSERTELEMENT = 365,
|
||||
SHUFFLEVECTOR = 366,
|
||||
VAARG_old = 367,
|
||||
VANEXT_old = 368
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#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 DLLIMPORT 300
|
||||
#define DLLEXPORT 301
|
||||
#define EXTERN_WEAK 302
|
||||
#define OPAQUE 303
|
||||
#define NOT 304
|
||||
#define EXTERNAL 305
|
||||
#define TARGET 306
|
||||
#define TRIPLE 307
|
||||
#define ENDIAN 308
|
||||
#define POINTERSIZE 309
|
||||
#define LITTLE 310
|
||||
#define BIG 311
|
||||
#define ALIGN 312
|
||||
#define DEPLIBS 313
|
||||
#define CALL 314
|
||||
#define TAIL 315
|
||||
#define ASM_TOK 316
|
||||
#define MODULE 317
|
||||
#define SIDEEFFECT 318
|
||||
#define CC_TOK 319
|
||||
#define CCC_TOK 320
|
||||
#define CSRETCC_TOK 321
|
||||
#define FASTCC_TOK 322
|
||||
#define COLDCC_TOK 323
|
||||
#define X86_STDCALLCC_TOK 324
|
||||
#define X86_FASTCALLCC_TOK 325
|
||||
#define DATALAYOUT 326
|
||||
#define RET 327
|
||||
#define BR 328
|
||||
#define SWITCH 329
|
||||
#define INVOKE 330
|
||||
#define UNWIND 331
|
||||
#define UNREACHABLE 332
|
||||
#define ADD 333
|
||||
#define SUB 334
|
||||
#define MUL 335
|
||||
#define UDIV 336
|
||||
#define SDIV 337
|
||||
#define FDIV 338
|
||||
#define UREM 339
|
||||
#define SREM 340
|
||||
#define FREM 341
|
||||
#define AND 342
|
||||
#define OR 343
|
||||
#define XOR 344
|
||||
#define SETLE 345
|
||||
#define SETGE 346
|
||||
#define SETLT 347
|
||||
#define SETGT 348
|
||||
#define SETEQ 349
|
||||
#define SETNE 350
|
||||
#define MALLOC 351
|
||||
#define ALLOCA 352
|
||||
#define FREE 353
|
||||
#define LOAD 354
|
||||
#define STORE 355
|
||||
#define GETELEMENTPTR 356
|
||||
#define PHI_TOK 357
|
||||
#define CAST 358
|
||||
#define SELECT 359
|
||||
#define SHL 360
|
||||
#define LSHR 361
|
||||
#define ASHR 362
|
||||
#define VAARG 363
|
||||
#define EXTRACTELEMENT 364
|
||||
#define INSERTELEMENT 365
|
||||
#define SHUFFLEVECTOR 366
|
||||
#define VAARG_old 367
|
||||
#define VANEXT_old 368
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
#line 1040 "/proj/llvm/llvm-3/lib/AsmParser/llvmAsmParser.y"
|
||||
typedef union YYSTYPE {
|
||||
llvm::Module *ModuleVal;
|
||||
llvm::Function *FunctionVal;
|
||||
std::pair<llvm::PATypeHolder*, char*> *ArgVal;
|
||||
@ -37,116 +299,14 @@ typedef union {
|
||||
OtherOpInfo 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 DLLIMPORT 299
|
||||
#define DLLEXPORT 300
|
||||
#define EXTERN_WEAK 301
|
||||
#define OPAQUE 302
|
||||
#define NOT 303
|
||||
#define EXTERNAL 304
|
||||
#define TARGET 305
|
||||
#define TRIPLE 306
|
||||
#define ENDIAN 307
|
||||
#define POINTERSIZE 308
|
||||
#define LITTLE 309
|
||||
#define BIG 310
|
||||
#define ALIGN 311
|
||||
#define DEPLIBS 312
|
||||
#define CALL 313
|
||||
#define TAIL 314
|
||||
#define ASM_TOK 315
|
||||
#define MODULE 316
|
||||
#define SIDEEFFECT 317
|
||||
#define CC_TOK 318
|
||||
#define CCC_TOK 319
|
||||
#define CSRETCC_TOK 320
|
||||
#define FASTCC_TOK 321
|
||||
#define COLDCC_TOK 322
|
||||
#define X86_STDCALLCC_TOK 323
|
||||
#define X86_FASTCALLCC_TOK 324
|
||||
#define DATALAYOUT 325
|
||||
#define RET 326
|
||||
#define BR 327
|
||||
#define SWITCH 328
|
||||
#define INVOKE 329
|
||||
#define UNWIND 330
|
||||
#define UNREACHABLE 331
|
||||
#define ADD 332
|
||||
#define SUB 333
|
||||
#define MUL 334
|
||||
#define UDIV 335
|
||||
#define SDIV 336
|
||||
#define FDIV 337
|
||||
#define UREM 338
|
||||
#define SREM 339
|
||||
#define FREM 340
|
||||
#define AND 341
|
||||
#define OR 342
|
||||
#define XOR 343
|
||||
#define SETLE 344
|
||||
#define SETGE 345
|
||||
#define SETLT 346
|
||||
#define SETGT 347
|
||||
#define SETEQ 348
|
||||
#define SETNE 349
|
||||
#define MALLOC 350
|
||||
#define ALLOCA 351
|
||||
#define FREE 352
|
||||
#define LOAD 353
|
||||
#define STORE 354
|
||||
#define GETELEMENTPTR 355
|
||||
#define PHI_TOK 356
|
||||
#define CAST 357
|
||||
#define SELECT 358
|
||||
#define SHL 359
|
||||
#define SHR 360
|
||||
#define VAARG 361
|
||||
#define EXTRACTELEMENT 362
|
||||
#define INSERTELEMENT 363
|
||||
#define SHUFFLEVECTOR 364
|
||||
#define VAARG_old 365
|
||||
#define VANEXT_old 366
|
||||
|
||||
/* Line 1447 of yacc.c. */
|
||||
#line 304 "llvmAsmParser.tab.h"
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE llvmAsmlval;
|
||||
|
||||
|
||||
|
||||
|
@ -820,7 +820,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
|
||||
/// an obsolete opcode. For example, "div" was replaced by [usf]div but we need
|
||||
/// to maintain backwards compatibility for asm files that still have the "div"
|
||||
/// instruction. This function handles converting div -> [usf]div appropriately.
|
||||
/// @brief Convert obsolete opcodes to new values
|
||||
/// @brief Convert obsolete BinaryOps opcodes to new values
|
||||
static void
|
||||
sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy)
|
||||
{
|
||||
@ -855,7 +855,31 @@ sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy)
|
||||
// Its not obsolete any more, we fixed it.
|
||||
OI.obsolete = false;
|
||||
}
|
||||
|
||||
|
||||
/// This function is similar to the previous overload of sanitizeOpCode but
|
||||
/// operates on Instruction::OtherOps instead of Instruction::BinaryOps.
|
||||
/// @brief Convert obsolete OtherOps opcodes to new values
|
||||
static void
|
||||
sanitizeOpCode(OpcodeInfo<Instruction::OtherOps> &OI, const PATypeHolder& PATy)
|
||||
{
|
||||
// If its not obsolete, don't do anything
|
||||
if (!OI.obsolete)
|
||||
return;
|
||||
|
||||
const Type* Ty = PATy; // type conversion
|
||||
switch (OI.opcode) {
|
||||
default:
|
||||
GenerateError("Invalid obsolete opcode (check Lexer.l)");
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
if (Ty->isSigned())
|
||||
OI.opcode = Instruction::AShr;
|
||||
break;
|
||||
}
|
||||
// Its not obsolete any more, we fixed it.
|
||||
OI.obsolete = false;
|
||||
}
|
||||
|
||||
// common code from the two 'RunVMAsmParser' functions
|
||||
static Module* RunParser(Module * M) {
|
||||
|
||||
@ -1126,7 +1150,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
||||
|
||||
// Other Operators
|
||||
%type <OtherOpVal> ShiftOps
|
||||
%token <OtherOpVal> PHI_TOK CAST SELECT SHL SHR VAARG
|
||||
%token <OtherOpVal> PHI_TOK CAST SELECT SHL LSHR ASHR VAARG
|
||||
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
|
||||
%token VAARG_old VANEXT_old //OBSOLETE
|
||||
|
||||
@ -1160,7 +1184,7 @@ ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
|
||||
LogicalOps : AND | OR | XOR;
|
||||
SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
|
||||
|
||||
ShiftOps : SHL | SHR;
|
||||
ShiftOps : SHL | LSHR | ASHR;
|
||||
|
||||
// These are some types that allow classification if we only want a particular
|
||||
// thing... for example, only a signed, unsigned, or integral type.
|
||||
@ -1730,6 +1754,9 @@ ConstExpr: CAST '(' ConstVal TO Types ')' {
|
||||
GEN_ERROR("Shift count for shift constant must be unsigned byte!");
|
||||
if (!$3->getType()->isInteger())
|
||||
GEN_ERROR("Shift constant expression requires integer operand!");
|
||||
// Handle opcode upgrade situations
|
||||
sanitizeOpCode($1, $3->getType());
|
||||
CHECK_FOR_ERROR;
|
||||
$$ = ConstantExpr::get($1.opcode, $3, $5);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
@ -2534,6 +2561,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
GEN_ERROR("Shift amount must be ubyte!");
|
||||
if (!$2->getType()->isInteger())
|
||||
GEN_ERROR("Shift constant expression requires integer operand!");
|
||||
// Handle opcode upgrade situations
|
||||
sanitizeOpCode($1, $2->getType());
|
||||
CHECK_FOR_ERROR;
|
||||
$$ = new ShiftInst($1.opcode, $2, $4);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
|
@ -820,7 +820,7 @@ static PATypeHolder HandleUpRefs(const Type *ty) {
|
||||
/// an obsolete opcode. For example, "div" was replaced by [usf]div but we need
|
||||
/// to maintain backwards compatibility for asm files that still have the "div"
|
||||
/// instruction. This function handles converting div -> [usf]div appropriately.
|
||||
/// @brief Convert obsolete opcodes to new values
|
||||
/// @brief Convert obsolete BinaryOps opcodes to new values
|
||||
static void
|
||||
sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy)
|
||||
{
|
||||
@ -855,7 +855,31 @@ sanitizeOpCode(OpcodeInfo<Instruction::BinaryOps> &OI, const PATypeHolder& PATy)
|
||||
// Its not obsolete any more, we fixed it.
|
||||
OI.obsolete = false;
|
||||
}
|
||||
|
||||
|
||||
/// This function is similar to the previous overload of sanitizeOpCode but
|
||||
/// operates on Instruction::OtherOps instead of Instruction::BinaryOps.
|
||||
/// @brief Convert obsolete OtherOps opcodes to new values
|
||||
static void
|
||||
sanitizeOpCode(OpcodeInfo<Instruction::OtherOps> &OI, const PATypeHolder& PATy)
|
||||
{
|
||||
// If its not obsolete, don't do anything
|
||||
if (!OI.obsolete)
|
||||
return;
|
||||
|
||||
const Type* Ty = PATy; // type conversion
|
||||
switch (OI.opcode) {
|
||||
default:
|
||||
GenerateError("Invalid obsolete opcode (check Lexer.l)");
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
if (Ty->isSigned())
|
||||
OI.opcode = Instruction::AShr;
|
||||
break;
|
||||
}
|
||||
// Its not obsolete any more, we fixed it.
|
||||
OI.obsolete = false;
|
||||
}
|
||||
|
||||
// common code from the two 'RunVMAsmParser' functions
|
||||
static Module* RunParser(Module * M) {
|
||||
|
||||
@ -1126,7 +1150,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
||||
|
||||
// Other Operators
|
||||
%type <OtherOpVal> ShiftOps
|
||||
%token <OtherOpVal> PHI_TOK CAST SELECT SHL SHR VAARG
|
||||
%token <OtherOpVal> PHI_TOK CAST SELECT SHL LSHR ASHR VAARG
|
||||
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
|
||||
%token VAARG_old VANEXT_old //OBSOLETE
|
||||
|
||||
@ -1160,7 +1184,7 @@ ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM;
|
||||
LogicalOps : AND | OR | XOR;
|
||||
SetCondOps : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE;
|
||||
|
||||
ShiftOps : SHL | SHR;
|
||||
ShiftOps : SHL | LSHR | ASHR;
|
||||
|
||||
// These are some types that allow classification if we only want a particular
|
||||
// thing... for example, only a signed, unsigned, or integral type.
|
||||
@ -1730,6 +1754,9 @@ ConstExpr: CAST '(' ConstVal TO Types ')' {
|
||||
GEN_ERROR("Shift count for shift constant must be unsigned byte!");
|
||||
if (!$3->getType()->isInteger())
|
||||
GEN_ERROR("Shift constant expression requires integer operand!");
|
||||
// Handle opcode upgrade situations
|
||||
sanitizeOpCode($1, $3->getType());
|
||||
CHECK_FOR_ERROR;
|
||||
$$ = ConstantExpr::get($1.opcode, $3, $5);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
@ -2534,6 +2561,9 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
GEN_ERROR("Shift amount must be ubyte!");
|
||||
if (!$2->getType()->isInteger())
|
||||
GEN_ERROR("Shift constant expression requires integer operand!");
|
||||
// Handle opcode upgrade situations
|
||||
sanitizeOpCode($1, $2->getType());
|
||||
CHECK_FOR_ERROR;
|
||||
$$ = new ShiftInst($1.opcode, $2, $4);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
|
@ -719,7 +719,15 @@ BytecodeReader::handleObsoleteOpcodes(
|
||||
Opcode = Instruction::Shl;
|
||||
break;
|
||||
case 31: // Shr
|
||||
Opcode = Instruction::Shr;
|
||||
// The type of the instruction is based on the operands. We need to
|
||||
// select ashr or lshr based on that type. The iType values are hardcoded
|
||||
// to the values used in bytecode version 5 (and prior) because it is
|
||||
// likely these codes will change in future versions of LLVM. This if
|
||||
// statement says "if (integer type and signed)"
|
||||
if (iType >= 2 && iType <= 9 && iType % 2 != 0)
|
||||
Opcode = Instruction::AShr;
|
||||
else
|
||||
Opcode = Instruction::LShr;
|
||||
break;
|
||||
case 32: { //VANext_old ( <= llvm 1.5 )
|
||||
const Type* ArgTy = getValue(iType, Oprnds[0])->getType();
|
||||
@ -987,7 +995,8 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
}
|
||||
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
Result = new ShiftInst(Instruction::OtherOps(Opcode),
|
||||
getValue(iType, Oprnds[0]),
|
||||
getValue(Type::UByteTyID, Oprnds[1]));
|
||||
@ -1707,7 +1716,10 @@ inline unsigned fixCEOpcodes(
|
||||
Opcode = Instruction::Shl;
|
||||
break;
|
||||
case 31: // Shr
|
||||
Opcode = Instruction::Shr;
|
||||
if (ArgVec[0]->getType()->isSigned())
|
||||
Opcode = Instruction::AShr;
|
||||
else
|
||||
Opcode = Instruction::LShr;
|
||||
break;
|
||||
case 34: // Select
|
||||
Opcode = Instruction::Select;
|
||||
|
@ -138,12 +138,6 @@ void DefaultIntrinsicLowering::AddPrototypes(Module &M) {
|
||||
static Value *LowerBSWAP(Value *V, Instruction *IP) {
|
||||
assert(V->getType()->isInteger() && "Can't bswap a non-integer type!");
|
||||
|
||||
const Type *DestTy = V->getType();
|
||||
|
||||
// Force to unsigned so that the shift rights are logical.
|
||||
if (DestTy->isSigned())
|
||||
V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP);
|
||||
|
||||
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
|
||||
|
||||
switch(BitSize) {
|
||||
@ -151,7 +145,7 @@ static Value *LowerBSWAP(Value *V, Instruction *IP) {
|
||||
case 16: {
|
||||
Value *Tmp1 = new ShiftInst(Instruction::Shl, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.2",IP);
|
||||
Value *Tmp2 = new ShiftInst(Instruction::Shr, V,
|
||||
Value *Tmp2 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.1",IP);
|
||||
V = BinaryOperator::createOr(Tmp1, Tmp2, "bswap.i16", IP);
|
||||
break;
|
||||
@ -160,10 +154,10 @@ static Value *LowerBSWAP(Value *V, Instruction *IP) {
|
||||
Value *Tmp4 = new ShiftInst(Instruction::Shl, V,
|
||||
ConstantInt::get(Type::UByteTy,24),"bswap.4", IP);
|
||||
Value *Tmp3 = new ShiftInst(Instruction::Shl, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.3",IP);
|
||||
Value *Tmp2 = new ShiftInst(Instruction::Shr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.2",IP);
|
||||
Value *Tmp1 = new ShiftInst(Instruction::Shr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.3",IP);
|
||||
Value *Tmp2 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.2",IP);
|
||||
Value *Tmp1 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,24),"bswap.1", IP);
|
||||
Tmp3 = BinaryOperator::createAnd(Tmp3,
|
||||
ConstantInt::get(Type::UIntTy, 0xFF0000),
|
||||
@ -184,14 +178,14 @@ static Value *LowerBSWAP(Value *V, Instruction *IP) {
|
||||
Value *Tmp6 = new ShiftInst(Instruction::Shl, V,
|
||||
ConstantInt::get(Type::UByteTy,24),"bswap.6", IP);
|
||||
Value *Tmp5 = new ShiftInst(Instruction::Shl, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.5",IP);
|
||||
Value *Tmp4 = new ShiftInst(Instruction::Shr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.4",IP);
|
||||
Value *Tmp3 = new ShiftInst(Instruction::Shr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.5", IP);
|
||||
Value* Tmp4 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,8),"bswap.4", IP);
|
||||
Value* Tmp3 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,24),"bswap.3", IP);
|
||||
Value *Tmp2 = new ShiftInst(Instruction::Shr, V,
|
||||
Value* Tmp2 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,40),"bswap.2", IP);
|
||||
Value *Tmp1 = new ShiftInst(Instruction::Shr, V,
|
||||
Value* Tmp1 = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy,56),"bswap.1", IP);
|
||||
Tmp7 = BinaryOperator::createAnd(Tmp7,
|
||||
ConstantInt::get(Type::ULongTy,
|
||||
@ -222,9 +216,6 @@ static Value *LowerBSWAP(Value *V, Instruction *IP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (V->getType() != DestTy)
|
||||
V = new CastInst(V, DestTy, V->getName(), IP);
|
||||
return V;
|
||||
}
|
||||
|
||||
@ -239,48 +230,33 @@ static Value *LowerCTPOP(Value *V, Instruction *IP) {
|
||||
0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
|
||||
};
|
||||
|
||||
const Type *DestTy = V->getType();
|
||||
|
||||
// Force to unsigned so that the shift rights are logical.
|
||||
if (DestTy->isSigned())
|
||||
V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP);
|
||||
|
||||
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
|
||||
|
||||
for (unsigned i = 1, ct = 0; i != BitSize; i <<= 1, ++ct) {
|
||||
Value *MaskCst =
|
||||
ConstantExpr::getCast(ConstantInt::get(Type::ULongTy, MaskValues[ct]),
|
||||
V->getType());
|
||||
Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP);
|
||||
Value *VShift = new ShiftInst(Instruction::Shr, V,
|
||||
Value *VShift = new ShiftInst(Instruction::LShr, V,
|
||||
ConstantInt::get(Type::UByteTy, i), "ctpop.sh", IP);
|
||||
Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
|
||||
V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);
|
||||
}
|
||||
|
||||
if (V->getType() != DestTy)
|
||||
V = new CastInst(V, DestTy, V->getName(), IP);
|
||||
return V;
|
||||
}
|
||||
|
||||
/// LowerCTLZ - Emit the code to lower ctlz of V before the specified
|
||||
/// instruction IP.
|
||||
static Value *LowerCTLZ(Value *V, Instruction *IP) {
|
||||
const Type *DestTy = V->getType();
|
||||
|
||||
// Force to unsigned so that the shift rights are logical.
|
||||
if (DestTy->isSigned())
|
||||
V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP);
|
||||
|
||||
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
|
||||
for (unsigned i = 1; i != BitSize; i <<= 1) {
|
||||
Value *ShVal = ConstantInt::get(Type::UByteTy, i);
|
||||
ShVal = new ShiftInst(Instruction::Shr, V, ShVal, "ctlz.sh", IP);
|
||||
ShVal = new ShiftInst(Instruction::LShr, V, ShVal, "ctlz.sh", IP);
|
||||
V = BinaryOperator::createOr(V, ShVal, "ctlz.step", IP);
|
||||
}
|
||||
|
||||
if (V->getType() != DestTy)
|
||||
V = new CastInst(V, DestTy, V->getName(), IP);
|
||||
|
||||
V = BinaryOperator::createNot(V, "", IP);
|
||||
return LowerCTPOP(V, IP);
|
||||
}
|
||||
|
@ -538,10 +538,8 @@ public:
|
||||
void visitOr (User &I) { visitIntBinary(I, ISD::OR, ISD::VOR); }
|
||||
void visitXor(User &I) { visitIntBinary(I, ISD::XOR, ISD::VXOR); }
|
||||
void visitShl(User &I) { visitShift(I, ISD::SHL); }
|
||||
void visitShr(User &I) {
|
||||
visitShift(I, I.getType()->isUnsigned() ? ISD::SRL : ISD::SRA);
|
||||
}
|
||||
|
||||
void visitLShr(User &I) { visitShift(I, ISD::SRL); }
|
||||
void visitAShr(User &I) { visitShift(I, ISD::SRA); }
|
||||
void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc,
|
||||
ISD::CondCode FPOpc);
|
||||
void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ,
|
||||
|
@ -72,8 +72,10 @@ static GenericValue executeSetGEInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty);
|
||||
static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty);
|
||||
static GenericValue executeShrInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty);
|
||||
static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty);
|
||||
static GenericValue executeAShrInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty);
|
||||
static GenericValue executeSelectInst(GenericValue Src1, GenericValue Src2,
|
||||
GenericValue Src3);
|
||||
|
||||
@ -161,10 +163,14 @@ GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE,
|
||||
return executeShlInst(getOperandValue(CE->getOperand(0), SF),
|
||||
getOperandValue(CE->getOperand(1), SF),
|
||||
CE->getOperand(0)->getType());
|
||||
case Instruction::Shr:
|
||||
return executeShrInst(getOperandValue(CE->getOperand(0), SF),
|
||||
getOperandValue(CE->getOperand(1), SF),
|
||||
CE->getOperand(0)->getType());
|
||||
case Instruction::LShr:
|
||||
return executeLShrInst(getOperandValue(CE->getOperand(0), SF),
|
||||
getOperandValue(CE->getOperand(1), SF),
|
||||
CE->getOperand(0)->getType());
|
||||
case Instruction::AShr:
|
||||
return executeAShrInst(getOperandValue(CE->getOperand(0), SF),
|
||||
getOperandValue(CE->getOperand(1), SF),
|
||||
CE->getOperand(0)->getType());
|
||||
case Instruction::Select:
|
||||
return executeSelectInst(getOperandValue(CE->getOperand(0), SF),
|
||||
getOperandValue(CE->getOperand(1), SF),
|
||||
@ -943,6 +949,10 @@ void Interpreter::visitCallSite(CallSite CS) {
|
||||
#define IMPLEMENT_SHIFT(OP, TY) \
|
||||
case Type::TY##TyID: Dest.TY##Val = Src1.TY##Val OP Src2.UByteVal; break
|
||||
|
||||
#define IMPLEMENT_SIGNLESS_SHIFT(OP, TY1, TY2) \
|
||||
case Type::TY2##TyID: \
|
||||
IMPLEMENT_SHIFT(OP, TY1)
|
||||
|
||||
static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty) {
|
||||
GenericValue Dest;
|
||||
@ -961,20 +971,31 @@ static GenericValue executeShlInst(GenericValue Src1, GenericValue Src2,
|
||||
return Dest;
|
||||
}
|
||||
|
||||
static GenericValue executeShrInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty) {
|
||||
static GenericValue executeLShrInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty) {
|
||||
GenericValue Dest;
|
||||
switch (Ty->getTypeID()) {
|
||||
IMPLEMENT_SHIFT(>>, UByte);
|
||||
IMPLEMENT_SHIFT(>>, SByte);
|
||||
IMPLEMENT_SHIFT(>>, UShort);
|
||||
IMPLEMENT_SHIFT(>>, Short);
|
||||
IMPLEMENT_SHIFT(>>, UInt);
|
||||
IMPLEMENT_SHIFT(>>, Int);
|
||||
IMPLEMENT_SHIFT(>>, ULong);
|
||||
IMPLEMENT_SHIFT(>>, Long);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, UByte, SByte);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, UShort, Short);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, UInt, Int);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, ULong, Long);
|
||||
default:
|
||||
std::cout << "Unhandled type for Shr instruction: " << *Ty << "\n";
|
||||
std::cout << "Unhandled type for LShr instruction: " << *Ty << "\n";
|
||||
abort();
|
||||
}
|
||||
return Dest;
|
||||
}
|
||||
|
||||
static GenericValue executeAShrInst(GenericValue Src1, GenericValue Src2,
|
||||
const Type *Ty) {
|
||||
GenericValue Dest;
|
||||
switch (Ty->getTypeID()) {
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, SByte, UByte);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, Short, UShort);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, Int, UInt);
|
||||
IMPLEMENT_SIGNLESS_SHIFT(>>, Long, ULong);
|
||||
default:
|
||||
std::cout << "Unhandled type for AShr instruction: " << *Ty << "\n";
|
||||
abort();
|
||||
}
|
||||
return Dest;
|
||||
@ -990,13 +1011,23 @@ void Interpreter::visitShl(ShiftInst &I) {
|
||||
SetValue(&I, Dest, SF);
|
||||
}
|
||||
|
||||
void Interpreter::visitShr(ShiftInst &I) {
|
||||
void Interpreter::visitLShr(ShiftInst &I) {
|
||||
ExecutionContext &SF = ECStack.back();
|
||||
const Type *Ty = I.getOperand(0)->getType();
|
||||
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
||||
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
||||
GenericValue Dest;
|
||||
Dest = executeShrInst (Src1, Src2, Ty);
|
||||
Dest = executeLShrInst (Src1, Src2, Ty);
|
||||
SetValue(&I, Dest, SF);
|
||||
}
|
||||
|
||||
void Interpreter::visitAShr(ShiftInst &I) {
|
||||
ExecutionContext &SF = ECStack.back();
|
||||
const Type *Ty = I.getOperand(0)->getType();
|
||||
GenericValue Src1 = getOperandValue(I.getOperand(0), SF);
|
||||
GenericValue Src2 = getOperandValue(I.getOperand(1), SF);
|
||||
GenericValue Dest;
|
||||
Dest = executeAShrInst (Src1, Src2, Ty);
|
||||
SetValue(&I, Dest, SF);
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,8 @@ public:
|
||||
void visitUnreachableInst(UnreachableInst &I);
|
||||
|
||||
void visitShl(ShiftInst &I);
|
||||
void visitShr(ShiftInst &I);
|
||||
void visitLShr(ShiftInst &I);
|
||||
void visitAShr(ShiftInst &I);
|
||||
void visitVAArgInst(VAArgInst &I);
|
||||
void visitInstruction(Instruction &I) {
|
||||
std::cerr << I;
|
||||
|
@ -606,7 +606,8 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
case Instruction::SetGT:
|
||||
case Instruction::SetGE:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
{
|
||||
Out << '(';
|
||||
bool NeedsClosingParens = printConstExprCast(CE);
|
||||
@ -631,7 +632,8 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
case Instruction::SetGT: Out << " > "; break;
|
||||
case Instruction::SetGE: Out << " >= "; break;
|
||||
case Instruction::Shl: Out << " << "; break;
|
||||
case Instruction::Shr: Out << " >> "; break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr: Out << " >> "; break;
|
||||
default: assert(0 && "Illegal opcode here!");
|
||||
}
|
||||
printConstantWithCast(CE->getOperand(1), CE->getOpcode());
|
||||
@ -826,23 +828,23 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
// because their operands were casted to the expected type. This function takes
|
||||
// care of detecting that case and printing the cast for the ConstantExpr.
|
||||
bool CWriter::printConstExprCast(const ConstantExpr* CE) {
|
||||
bool Result = false;
|
||||
bool NeedsExplicitCast = false;
|
||||
const Type* Ty = CE->getOperand(0)->getType();
|
||||
switch (CE->getOpcode()) {
|
||||
case Instruction::UDiv:
|
||||
case Instruction::LShr:
|
||||
case Instruction::URem:
|
||||
Result = Ty->isSigned(); break;
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SRem:
|
||||
Result = Ty->isUnsigned(); break;
|
||||
case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
|
||||
default: break;
|
||||
}
|
||||
if (Result) {
|
||||
if (NeedsExplicitCast) {
|
||||
Out << "((";
|
||||
printType(Out, Ty);
|
||||
Out << ")(";
|
||||
}
|
||||
return Result;
|
||||
return NeedsExplicitCast;
|
||||
}
|
||||
|
||||
// Print a constant assuming that it is the operand for a given Opcode. The
|
||||
@ -863,6 +865,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
|
||||
default:
|
||||
// for most instructions, it doesn't matter
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// For UDiv/URem get correct type
|
||||
@ -871,6 +874,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
|
||||
shouldCast = true;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem:
|
||||
// For SDiv/SRem get correct type
|
||||
@ -927,23 +931,23 @@ void CWriter::writeOperand(Value *Operand) {
|
||||
// This function takes care of detecting that case and printing the cast
|
||||
// for the Instruction.
|
||||
bool CWriter::writeInstructionCast(const Instruction &I) {
|
||||
bool Result = false;
|
||||
bool NeedsExplicitCast = false;
|
||||
const Type* Ty = I.getOperand(0)->getType();
|
||||
switch (I.getOpcode()) {
|
||||
case Instruction::UDiv:
|
||||
case Instruction::LShr:
|
||||
case Instruction::URem:
|
||||
Result = Ty->isSigned(); break;
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SRem:
|
||||
Result = Ty->isUnsigned(); break;
|
||||
case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
|
||||
default: break;
|
||||
}
|
||||
if (Result) {
|
||||
if (NeedsExplicitCast) {
|
||||
Out << "((";
|
||||
printType(Out, Ty);
|
||||
Out << ")(";
|
||||
}
|
||||
return Result;
|
||||
return NeedsExplicitCast;
|
||||
}
|
||||
|
||||
// Write the operand with a cast to another type based on the Opcode being used.
|
||||
@ -964,6 +968,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
default:
|
||||
// for most instructions, it doesn't matter
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// For UDiv to have unsigned operands
|
||||
@ -972,6 +977,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
shouldCast = true;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem:
|
||||
if (OpTy->isUnsigned()) {
|
||||
@ -1832,7 +1838,8 @@ void CWriter::visitBinaryOperator(Instruction &I) {
|
||||
case Instruction::SetLT: Out << " < "; break;
|
||||
case Instruction::SetGT: Out << " > "; break;
|
||||
case Instruction::Shl : Out << " << "; break;
|
||||
case Instruction::Shr : Out << " >> "; break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr: Out << " >> "; break;
|
||||
default: std::cerr << "Invalid operator type!" << I; abort();
|
||||
}
|
||||
|
||||
|
@ -606,7 +606,8 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
case Instruction::SetGT:
|
||||
case Instruction::SetGE:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
{
|
||||
Out << '(';
|
||||
bool NeedsClosingParens = printConstExprCast(CE);
|
||||
@ -631,7 +632,8 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
case Instruction::SetGT: Out << " > "; break;
|
||||
case Instruction::SetGE: Out << " >= "; break;
|
||||
case Instruction::Shl: Out << " << "; break;
|
||||
case Instruction::Shr: Out << " >> "; break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr: Out << " >> "; break;
|
||||
default: assert(0 && "Illegal opcode here!");
|
||||
}
|
||||
printConstantWithCast(CE->getOperand(1), CE->getOpcode());
|
||||
@ -826,23 +828,23 @@ void CWriter::printConstant(Constant *CPV) {
|
||||
// because their operands were casted to the expected type. This function takes
|
||||
// care of detecting that case and printing the cast for the ConstantExpr.
|
||||
bool CWriter::printConstExprCast(const ConstantExpr* CE) {
|
||||
bool Result = false;
|
||||
bool NeedsExplicitCast = false;
|
||||
const Type* Ty = CE->getOperand(0)->getType();
|
||||
switch (CE->getOpcode()) {
|
||||
case Instruction::UDiv:
|
||||
case Instruction::LShr:
|
||||
case Instruction::URem:
|
||||
Result = Ty->isSigned(); break;
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SRem:
|
||||
Result = Ty->isUnsigned(); break;
|
||||
case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
|
||||
default: break;
|
||||
}
|
||||
if (Result) {
|
||||
if (NeedsExplicitCast) {
|
||||
Out << "((";
|
||||
printType(Out, Ty);
|
||||
Out << ")(";
|
||||
}
|
||||
return Result;
|
||||
return NeedsExplicitCast;
|
||||
}
|
||||
|
||||
// Print a constant assuming that it is the operand for a given Opcode. The
|
||||
@ -863,6 +865,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
|
||||
default:
|
||||
// for most instructions, it doesn't matter
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// For UDiv/URem get correct type
|
||||
@ -871,6 +874,7 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
|
||||
shouldCast = true;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem:
|
||||
// For SDiv/SRem get correct type
|
||||
@ -927,23 +931,23 @@ void CWriter::writeOperand(Value *Operand) {
|
||||
// This function takes care of detecting that case and printing the cast
|
||||
// for the Instruction.
|
||||
bool CWriter::writeInstructionCast(const Instruction &I) {
|
||||
bool Result = false;
|
||||
bool NeedsExplicitCast = false;
|
||||
const Type* Ty = I.getOperand(0)->getType();
|
||||
switch (I.getOpcode()) {
|
||||
case Instruction::UDiv:
|
||||
case Instruction::LShr:
|
||||
case Instruction::URem:
|
||||
Result = Ty->isSigned(); break;
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv: NeedsExplicitCast = Ty->isSigned(); break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SRem:
|
||||
Result = Ty->isUnsigned(); break;
|
||||
case Instruction::SDiv: NeedsExplicitCast = Ty->isUnsigned(); break;
|
||||
default: break;
|
||||
}
|
||||
if (Result) {
|
||||
if (NeedsExplicitCast) {
|
||||
Out << "((";
|
||||
printType(Out, Ty);
|
||||
Out << ")(";
|
||||
}
|
||||
return Result;
|
||||
return NeedsExplicitCast;
|
||||
}
|
||||
|
||||
// Write the operand with a cast to another type based on the Opcode being used.
|
||||
@ -964,6 +968,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
default:
|
||||
// for most instructions, it doesn't matter
|
||||
break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// For UDiv to have unsigned operands
|
||||
@ -972,6 +977,7 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
shouldCast = true;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem:
|
||||
if (OpTy->isUnsigned()) {
|
||||
@ -1832,7 +1838,8 @@ void CWriter::visitBinaryOperator(Instruction &I) {
|
||||
case Instruction::SetLT: Out << " < "; break;
|
||||
case Instruction::SetGT: Out << " > "; break;
|
||||
case Instruction::Shl : Out << " << "; break;
|
||||
case Instruction::Shr : Out << " >> "; break;
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr: Out << " >> "; break;
|
||||
default: std::cerr << "Invalid operator type!" << I; abort();
|
||||
}
|
||||
|
||||
|
@ -76,10 +76,12 @@ bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty,
|
||||
!ExpressionConvertibleToType(I->getOperand(1), Ty, CTMap, TD))
|
||||
return false;
|
||||
break;
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
if (!Ty->isInteger()) return false;
|
||||
if (Ty->isSigned() != V->getType()->isSigned()) return false;
|
||||
// FALL THROUGH
|
||||
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD))
|
||||
return false;
|
||||
break;
|
||||
case Instruction::Shl:
|
||||
if (!Ty->isInteger()) return false;
|
||||
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD))
|
||||
@ -243,7 +245,8 @@ Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty,
|
||||
break;
|
||||
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(), Dummy,
|
||||
I->getOperand(1), Name);
|
||||
VMC.ExprMap[I] = Res;
|
||||
@ -476,7 +479,8 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
|
||||
Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
|
||||
return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
|
||||
}
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
if (Ty->isSigned() != V->getType()->isSigned()) return false;
|
||||
// FALL THROUGH
|
||||
case Instruction::Shl:
|
||||
@ -746,7 +750,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
|
||||
break;
|
||||
}
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
assert(I->getOperand(0) == OldVal);
|
||||
Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(), NewVal,
|
||||
I->getOperand(1), Name);
|
||||
|
@ -731,7 +731,7 @@ static void ComputeMaskedBits(Value *V, uint64_t Mask, uint64_t &KnownZero,
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
|
||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||
// Compute the new bits that are at the top now.
|
||||
@ -739,29 +739,39 @@ static void ComputeMaskedBits(Value *V, uint64_t Mask, uint64_t &KnownZero,
|
||||
uint64_t HighBits = (1ULL << ShiftAmt)-1;
|
||||
HighBits <<= I->getType()->getPrimitiveSizeInBits()-ShiftAmt;
|
||||
|
||||
if (I->getType()->isUnsigned()) { // Unsigned shift right.
|
||||
Mask <<= ShiftAmt;
|
||||
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
KnownZero |= HighBits; // high bits known zero.
|
||||
} else {
|
||||
Mask <<= ShiftAmt;
|
||||
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
// Unsigned shift right.
|
||||
Mask <<= ShiftAmt;
|
||||
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
KnownZero |= HighBits; // high bits known zero.
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
// (ushr X, C1) & C2 == 0 iff (-1 >> C1) & C2 == 0
|
||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||
// Compute the new bits that are at the top now.
|
||||
uint64_t ShiftAmt = SA->getZExtValue();
|
||||
uint64_t HighBits = (1ULL << ShiftAmt)-1;
|
||||
HighBits <<= I->getType()->getPrimitiveSizeInBits()-ShiftAmt;
|
||||
|
||||
// Signed shift right.
|
||||
Mask <<= ShiftAmt;
|
||||
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero,KnownOne,Depth+1);
|
||||
assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
|
||||
// Handle the sign bits.
|
||||
uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
|
||||
SignBit >>= ShiftAmt; // Adjust to where it is now in the mask.
|
||||
// Handle the sign bits.
|
||||
uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
|
||||
SignBit >>= ShiftAmt; // Adjust to where it is now in the mask.
|
||||
|
||||
if (KnownZero & SignBit) { // New bits are known zero.
|
||||
KnownZero |= HighBits;
|
||||
} else if (KnownOne & SignBit) { // New bits are known one.
|
||||
KnownOne |= HighBits;
|
||||
}
|
||||
if (KnownZero & SignBit) { // New bits are known zero.
|
||||
KnownZero |= HighBits;
|
||||
} else if (KnownOne & SignBit) { // New bits are known one.
|
||||
KnownOne |= HighBits;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1119,21 +1129,37 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask,
|
||||
KnownZero |= (1ULL << ShiftAmt) - 1; // low bits known zero.
|
||||
}
|
||||
break;
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
// For a logical shift right
|
||||
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||
unsigned ShiftAmt = SA->getZExtValue();
|
||||
|
||||
// Compute the new bits that are at the top now.
|
||||
uint64_t HighBits = (1ULL << ShiftAmt)-1;
|
||||
HighBits <<= I->getType()->getPrimitiveSizeInBits() - ShiftAmt;
|
||||
uint64_t TypeMask = I->getType()->getIntegralTypeMask();
|
||||
// Unsigned shift right.
|
||||
if (SimplifyDemandedBits(I->getOperand(0),
|
||||
(DemandedMask << ShiftAmt) & TypeMask,
|
||||
KnownZero, KnownOne, Depth+1))
|
||||
return true;
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
KnownZero &= TypeMask;
|
||||
KnownOne &= TypeMask;
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
KnownZero |= HighBits; // high bits known zero.
|
||||
}
|
||||
break;
|
||||
case Instruction::AShr:
|
||||
// If this is an arithmetic shift right and only the low-bit is set, we can
|
||||
// always convert this into a logical shr, even if the shift amount is
|
||||
// variable. The low bit of the shift cannot be an input sign bit unless
|
||||
// the shift amount is >= the size of the datatype, which is undefined.
|
||||
if (DemandedMask == 1 && I->getType()->isSigned()) {
|
||||
// Convert the input to unsigned.
|
||||
Value *NewVal = InsertCastBefore(I->getOperand(0),
|
||||
I->getType()->getUnsignedVersion(), *I);
|
||||
// Perform the unsigned shift right.
|
||||
NewVal = new ShiftInst(Instruction::Shr, NewVal, I->getOperand(1),
|
||||
I->getName());
|
||||
InsertNewInstBefore(cast<Instruction>(NewVal), *I);
|
||||
// Then cast that to the destination type.
|
||||
NewVal = new CastInst(NewVal, I->getType(), I->getName());
|
||||
if (DemandedMask == 1) {
|
||||
// Perform the logical shift right.
|
||||
Value *NewVal = new ShiftInst(Instruction::LShr, I->getOperand(0),
|
||||
I->getOperand(1), I->getName());
|
||||
InsertNewInstBefore(cast<Instruction>(NewVal), *I);
|
||||
return UpdateValueUsesWith(I, NewVal);
|
||||
}
|
||||
@ -1145,48 +1171,31 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, uint64_t DemandedMask,
|
||||
uint64_t HighBits = (1ULL << ShiftAmt)-1;
|
||||
HighBits <<= I->getType()->getPrimitiveSizeInBits() - ShiftAmt;
|
||||
uint64_t TypeMask = I->getType()->getIntegralTypeMask();
|
||||
if (I->getType()->isUnsigned()) { // Unsigned shift right.
|
||||
if (SimplifyDemandedBits(I->getOperand(0),
|
||||
(DemandedMask << ShiftAmt) & TypeMask,
|
||||
KnownZero, KnownOne, Depth+1))
|
||||
return true;
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
KnownZero &= TypeMask;
|
||||
KnownOne &= TypeMask;
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
KnownZero |= HighBits; // high bits known zero.
|
||||
} else { // Signed shift right.
|
||||
if (SimplifyDemandedBits(I->getOperand(0),
|
||||
(DemandedMask << ShiftAmt) & TypeMask,
|
||||
KnownZero, KnownOne, Depth+1))
|
||||
return true;
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
KnownZero &= TypeMask;
|
||||
KnownOne &= TypeMask;
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
// Signed shift right.
|
||||
if (SimplifyDemandedBits(I->getOperand(0),
|
||||
(DemandedMask << ShiftAmt) & TypeMask,
|
||||
KnownZero, KnownOne, Depth+1))
|
||||
return true;
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
KnownZero &= TypeMask;
|
||||
KnownOne &= TypeMask;
|
||||
KnownZero >>= ShiftAmt;
|
||||
KnownOne >>= ShiftAmt;
|
||||
|
||||
// Handle the sign bits.
|
||||
uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
|
||||
SignBit >>= ShiftAmt; // Adjust to where it is now in the mask.
|
||||
// Handle the sign bits.
|
||||
uint64_t SignBit = 1ULL << (I->getType()->getPrimitiveSizeInBits()-1);
|
||||
SignBit >>= ShiftAmt; // Adjust to where it is now in the mask.
|
||||
|
||||
// If the input sign bit is known to be zero, or if none of the top bits
|
||||
// are demanded, turn this into an unsigned shift right.
|
||||
if ((KnownZero & SignBit) || (HighBits & ~DemandedMask) == HighBits) {
|
||||
// Convert the input to unsigned.
|
||||
Value *NewVal = InsertCastBefore(I->getOperand(0),
|
||||
I->getType()->getUnsignedVersion(), *I);
|
||||
// Perform the unsigned shift right.
|
||||
NewVal = new ShiftInst(Instruction::Shr, NewVal, SA, I->getName());
|
||||
InsertNewInstBefore(cast<Instruction>(NewVal), *I);
|
||||
// Then cast that to the destination type.
|
||||
NewVal = new CastInst(NewVal, I->getType(), I->getName());
|
||||
InsertNewInstBefore(cast<Instruction>(NewVal), *I);
|
||||
return UpdateValueUsesWith(I, NewVal);
|
||||
} else if (KnownOne & SignBit) { // New bits are known one.
|
||||
KnownOne |= HighBits;
|
||||
}
|
||||
// If the input sign bit is known to be zero, or if none of the top bits
|
||||
// are demanded, turn this into an unsigned shift right.
|
||||
if ((KnownZero & SignBit) || (HighBits & ~DemandedMask) == HighBits) {
|
||||
// Perform the logical shift right.
|
||||
Value *NewVal = new ShiftInst(Instruction::LShr, I->getOperand(0),
|
||||
SA, I->getName());
|
||||
InsertNewInstBefore(cast<Instruction>(NewVal), *I);
|
||||
return UpdateValueUsesWith(I, NewVal);
|
||||
} else if (KnownOne & SignBit) { // New bits are known one.
|
||||
KnownOne |= HighBits;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1899,29 +1908,28 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
if (C->isNullValue()) {
|
||||
Value *NoopCastedRHS = RemoveNoopCast(Op1);
|
||||
if (ShiftInst *SI = dyn_cast<ShiftInst>(NoopCastedRHS))
|
||||
if (SI->getOpcode() == Instruction::Shr)
|
||||
if (SI->getOpcode() == Instruction::LShr) {
|
||||
if (ConstantInt *CU = dyn_cast<ConstantInt>(SI->getOperand(1))) {
|
||||
const Type *NewTy;
|
||||
if (SI->getType()->isSigned())
|
||||
NewTy = SI->getType()->getUnsignedVersion();
|
||||
else
|
||||
NewTy = SI->getType()->getSignedVersion();
|
||||
// Check to see if we are shifting out everything but the sign bit.
|
||||
if (CU->getZExtValue() ==
|
||||
SI->getType()->getPrimitiveSizeInBits()-1) {
|
||||
// Ok, the transformation is safe. Insert a cast of the incoming
|
||||
// value, then the new shift, then the new cast.
|
||||
Value *InV = InsertCastBefore(SI->getOperand(0), NewTy, I);
|
||||
Instruction *NewShift = new ShiftInst(Instruction::Shr, InV,
|
||||
CU, SI->getName());
|
||||
if (NewShift->getType() == I.getType())
|
||||
return NewShift;
|
||||
else {
|
||||
InsertNewInstBefore(NewShift, I);
|
||||
return new CastInst(NewShift, I.getType());
|
||||
}
|
||||
// Ok, the transformation is safe. Insert AShr.
|
||||
return new ShiftInst(Instruction::AShr, SI->getOperand(0),
|
||||
CU, SI->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SI->getOpcode() == Instruction::AShr) {
|
||||
if (ConstantInt *CU = dyn_cast<ConstantInt>(SI->getOperand(1))) {
|
||||
// Check to see if we are shifting out everything but the sign bit.
|
||||
if (CU->getZExtValue() ==
|
||||
SI->getType()->getPrimitiveSizeInBits()-1) {
|
||||
// Ok, the transformation is safe. Insert LShr.
|
||||
return new ShiftInst(Instruction::LShr, SI->getOperand(0),
|
||||
CU, SI->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to fold constant sub into select arguments.
|
||||
@ -2138,7 +2146,7 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
|
||||
}
|
||||
|
||||
Value *V =
|
||||
InsertNewInstBefore(new ShiftInst(Instruction::Shr, SCIOp0, Amt,
|
||||
InsertNewInstBefore(new ShiftInst(Instruction::AShr, SCIOp0, Amt,
|
||||
BoolCast->getOperand(0)->getName()+
|
||||
".mask"), I);
|
||||
|
||||
@ -2262,18 +2270,8 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
||||
if (uint64_t Val = C->getZExtValue()) // Don't break X / 0
|
||||
if (isPowerOf2_64(Val)) {
|
||||
uint64_t ShiftAmt = Log2_64(Val);
|
||||
Value* X = Op0;
|
||||
const Type* XTy = X->getType();
|
||||
bool isSigned = XTy->isSigned();
|
||||
if (isSigned)
|
||||
X = InsertCastBefore(X, XTy->getUnsignedVersion(), I);
|
||||
Instruction* Result =
|
||||
new ShiftInst(Instruction::Shr, X,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt));
|
||||
if (!isSigned)
|
||||
return Result;
|
||||
InsertNewInstBefore(Result, I);
|
||||
return new CastInst(Result, XTy->getSignedVersion(), I.getName());
|
||||
return new ShiftInst(Instruction::LShr, Op0,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2285,20 +2283,11 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
||||
if (isPowerOf2_64(C1)) {
|
||||
Value *N = RHSI->getOperand(1);
|
||||
const Type* NTy = N->getType();
|
||||
bool isSigned = NTy->isSigned();
|
||||
if (uint64_t C2 = Log2_64(C1)) {
|
||||
if (isSigned) {
|
||||
NTy = NTy->getUnsignedVersion();
|
||||
N = InsertCastBefore(N, NTy, I);
|
||||
}
|
||||
Constant *C2V = ConstantInt::get(NTy, C2);
|
||||
N = InsertNewInstBefore(BinaryOperator::createAdd(N, C2V, "tmp"), I);
|
||||
}
|
||||
Instruction* Result = new ShiftInst(Instruction::Shr, Op0, N);
|
||||
if (!isSigned)
|
||||
return Result;
|
||||
InsertNewInstBefore(Result, I);
|
||||
return new CastInst(Result, NTy->getSignedVersion(), I.getName());
|
||||
return new ShiftInst(Instruction::LShr, Op0, N);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2313,31 +2302,20 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
|
||||
if (isPowerOf2_64(TVA) && isPowerOf2_64(FVA)) {
|
||||
// Compute the shift amounts
|
||||
unsigned TSA = Log2_64(TVA), FSA = Log2_64(FVA);
|
||||
// Make sure we get the unsigned version of X
|
||||
Value* X = Op0;
|
||||
const Type* origXTy = X->getType();
|
||||
bool isSigned = origXTy->isSigned();
|
||||
if (isSigned)
|
||||
X = InsertCastBefore(X, X->getType()->getUnsignedVersion(), I);
|
||||
// Construct the "on true" case of the select
|
||||
Constant *TC = ConstantInt::get(Type::UByteTy, TSA);
|
||||
Instruction *TSI =
|
||||
new ShiftInst(Instruction::Shr, X, TC, SI->getName()+".t");
|
||||
new ShiftInst(Instruction::LShr, Op0, TC, SI->getName()+".t");
|
||||
TSI = InsertNewInstBefore(TSI, I);
|
||||
|
||||
// Construct the "on false" case of the select
|
||||
Constant *FC = ConstantInt::get(Type::UByteTy, FSA);
|
||||
Instruction *FSI =
|
||||
new ShiftInst(Instruction::Shr, X, FC, SI->getName()+".f");
|
||||
new ShiftInst(Instruction::LShr, Op0, FC, SI->getName()+".f");
|
||||
FSI = InsertNewInstBefore(FSI, I);
|
||||
|
||||
// construct the select instruction and return it.
|
||||
SelectInst* NewSI =
|
||||
new SelectInst(SI->getOperand(0), TSI, FSI, SI->getName());
|
||||
if (!isSigned)
|
||||
return NewSI;
|
||||
InsertNewInstBefore(NewSI, I);
|
||||
return new CastInst(NewSI, origXTy, NewSI->getName());
|
||||
return new SelectInst(SI->getOperand(0), TSI, FSI, SI->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2807,44 +2785,40 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
{
|
||||
// We know that the AND will not produce any of the bits shifted in, so if
|
||||
// the anded constant includes them, clear them now! This only applies to
|
||||
// unsigned shifts, because a signed shr may bring in set bits!
|
||||
//
|
||||
if (AndRHS->getType()->isUnsigned()) {
|
||||
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
||||
Constant *ShrMask = ConstantExpr::getShr(AllOne, OpRHS);
|
||||
Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
|
||||
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
||||
Constant *ShrMask = ConstantExpr::getLShr(AllOne, OpRHS);
|
||||
Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
|
||||
|
||||
if (CI == ShrMask) { // Masking out bits that the shift already masks.
|
||||
return ReplaceInstUsesWith(TheAnd, Op);
|
||||
} else if (CI != AndRHS) {
|
||||
TheAnd.setOperand(1, CI); // Reduce bits set in and cst.
|
||||
return &TheAnd;
|
||||
}
|
||||
} else { // Signed shr.
|
||||
// See if this is shifting in some sign extension, then masking it out
|
||||
// with an and.
|
||||
if (Op->hasOneUse()) {
|
||||
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
||||
Constant *ShrMask = ConstantExpr::getUShr(AllOne, OpRHS);
|
||||
Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
|
||||
if (CI == AndRHS) { // Masking out bits shifted in.
|
||||
// Make the argument unsigned.
|
||||
Value *ShVal = Op->getOperand(0);
|
||||
ShVal = InsertCastBefore(ShVal,
|
||||
ShVal->getType()->getUnsignedVersion(),
|
||||
TheAnd);
|
||||
ShVal = InsertNewInstBefore(new ShiftInst(Instruction::Shr, ShVal,
|
||||
OpRHS, Op->getName()),
|
||||
TheAnd);
|
||||
Value *AndRHS2 = ConstantExpr::getCast(AndRHS, ShVal->getType());
|
||||
ShVal = InsertNewInstBefore(BinaryOperator::createAnd(ShVal, AndRHS2,
|
||||
TheAnd.getName()),
|
||||
TheAnd);
|
||||
return new CastInst(ShVal, Op->getType());
|
||||
}
|
||||
if (CI == ShrMask) { // Masking out bits that the shift already masks.
|
||||
return ReplaceInstUsesWith(TheAnd, Op);
|
||||
} else if (CI != AndRHS) {
|
||||
TheAnd.setOperand(1, CI); // Reduce bits set in and cst.
|
||||
return &TheAnd;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::AShr:
|
||||
// Signed shr.
|
||||
// See if this is shifting in some sign extension, then masking it out
|
||||
// with an and.
|
||||
if (Op->hasOneUse()) {
|
||||
Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
|
||||
Constant *ShrMask = ConstantExpr::getLShr(AllOne, OpRHS);
|
||||
Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
|
||||
if (CI == AndRHS) { // Masking out bits shifted in.
|
||||
// Make the argument unsigned.
|
||||
Value *ShVal = Op->getOperand(0);
|
||||
ShVal = InsertNewInstBefore(new ShiftInst(Instruction::LShr, ShVal,
|
||||
OpRHS, Op->getName()),
|
||||
TheAnd);
|
||||
Value *AndRHS2 = ConstantExpr::getCast(AndRHS, ShVal->getType());
|
||||
return BinaryOperator::createAnd(ShVal, AndRHS2, TheAnd.getName());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4294,7 +4268,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
if (CanFold) {
|
||||
Constant *NewCst;
|
||||
if (Shift->getOpcode() == Instruction::Shl)
|
||||
NewCst = ConstantExpr::getUShr(CI, ShAmt);
|
||||
NewCst = ConstantExpr::getLShr(CI, ShAmt);
|
||||
else
|
||||
NewCst = ConstantExpr::getShl(CI, ShAmt);
|
||||
|
||||
@ -4312,7 +4286,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
I.setOperand(1, NewCst);
|
||||
Constant *NewAndCST;
|
||||
if (Shift->getOpcode() == Instruction::Shl)
|
||||
NewAndCST = ConstantExpr::getUShr(AndCST, ShAmt);
|
||||
NewAndCST = ConstantExpr::getLShr(AndCST, ShAmt);
|
||||
else
|
||||
NewAndCST = ConstantExpr::getShl(AndCST, ShAmt);
|
||||
LHSI->setOperand(1, NewAndCST);
|
||||
@ -4338,7 +4312,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
isa<Instruction>(Shift->getOperand(0))) {
|
||||
// Compute C << Y.
|
||||
Value *NS;
|
||||
if (Shift->getOpcode() == Instruction::Shr) {
|
||||
if (Shift->getOpcode() == Instruction::LShr) {
|
||||
NS = new ShiftInst(Instruction::Shl, AndCST, Shift->getOperand(1),
|
||||
"tmp");
|
||||
} else {
|
||||
@ -4347,7 +4321,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
if (AndCST->getType()->isSigned())
|
||||
NewAndCST = ConstantExpr::getCast(AndCST,
|
||||
AndCST->getType()->getUnsignedVersion());
|
||||
NS = new ShiftInst(Instruction::Shr, NewAndCST,
|
||||
NS = new ShiftInst(Instruction::LShr, NewAndCST,
|
||||
Shift->getOperand(1), "tmp");
|
||||
}
|
||||
InsertNewInstBefore(cast<Instruction>(NS), I);
|
||||
@ -4385,7 +4359,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
// If we are comparing against bits always shifted out, the
|
||||
// comparison cannot succeed.
|
||||
Constant *Comp =
|
||||
ConstantExpr::getShl(ConstantExpr::getShr(CI, ShAmt), ShAmt);
|
||||
ConstantExpr::getShl(ConstantExpr::getLShr(CI, ShAmt), ShAmt);
|
||||
if (Comp != CI) {// Comparing against a bit that we know is zero.
|
||||
bool IsSetNE = I.getOpcode() == Instruction::SetNE;
|
||||
Constant *Cst = ConstantBool::get(IsSetNE);
|
||||
@ -4411,13 +4385,14 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
Mask, LHSI->getName()+".mask");
|
||||
Value *And = InsertNewInstBefore(AndI, I);
|
||||
return new SetCondInst(I.getOpcode(), And,
|
||||
ConstantExpr::getUShr(CI, ShAmt));
|
||||
ConstantExpr::getLShr(CI, ShAmt));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Instruction::Shr: // (setcc (shr X, ShAmt), CI)
|
||||
case Instruction::LShr: // (setcc (shr X, ShAmt), CI)
|
||||
case Instruction::AShr:
|
||||
if (ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
|
||||
if (I.isEquality()) {
|
||||
// Check that the shift amount is in range. If not, don't perform
|
||||
@ -4429,8 +4404,13 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
|
||||
|
||||
// If we are comparing against bits always shifted out, the
|
||||
// comparison cannot succeed.
|
||||
Constant *Comp =
|
||||
ConstantExpr::getShr(ConstantExpr::getShl(CI, ShAmt), ShAmt);
|
||||
Constant *Comp;
|
||||
if (CI->getType()->isUnsigned())
|
||||
Comp = ConstantExpr::getLShr(ConstantExpr::getShl(CI, ShAmt),
|
||||
ShAmt);
|
||||
else
|
||||
Comp = ConstantExpr::getAShr(ConstantExpr::getShl(CI, ShAmt),
|
||||
ShAmt);
|
||||
|
||||
if (Comp != CI) {// Comparing against a bit that we know is zero.
|
||||
bool IsSetNE = I.getOpcode() == Instruction::SetNE;
|
||||
@ -5019,10 +4999,7 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
|
||||
if (I.isArithmeticShift()) {
|
||||
if (MaskedValueIsZero(Op0,
|
||||
1ULL << (I.getType()->getPrimitiveSizeInBits()-1))) {
|
||||
Value *V = InsertCastBefore(Op0, I.getType()->getUnsignedVersion(), I);
|
||||
V = InsertNewInstBefore(new ShiftInst(Instruction::Shr, V, Op1,
|
||||
I.getName()), I);
|
||||
return new CastInst(V, I.getType());
|
||||
return new ShiftInst(Instruction::LShr, Op0, Op1, I.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5036,7 +5013,8 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
|
||||
Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
||||
ShiftInst &I) {
|
||||
bool isLeftShift = I.getOpcode() == Instruction::Shl;
|
||||
bool isSignedShift = Op0->getType()->isSigned();
|
||||
bool isSignedShift = isLeftShift ? Op0->getType()->isSigned() :
|
||||
I.getOpcode() == Instruction::AShr;
|
||||
bool isUnsignedShift = !isSignedShift;
|
||||
|
||||
// See if we can simplify any instructions used by the instruction whose sole
|
||||
@ -5229,7 +5207,9 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
||||
// signedness of the input shift may differ from the current shift if there
|
||||
// is a noop cast between the two.
|
||||
bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl;
|
||||
bool isShiftOfSignedShift = ShiftOp->getType()->isSigned();
|
||||
bool isShiftOfSignedShift = isShiftOfLeftShift ?
|
||||
ShiftOp->getType()->isSigned() :
|
||||
ShiftOp->getOpcode() == Instruction::AShr;
|
||||
bool isShiftOfUnsignedShift = !isShiftOfSignedShift;
|
||||
|
||||
ConstantInt *ShiftAmt1C = cast<ConstantInt>(ShiftOp->getOperand(1));
|
||||
@ -5252,8 +5232,12 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
||||
Value *Op = ShiftOp->getOperand(0);
|
||||
if (isShiftOfSignedShift != isSignedShift)
|
||||
Op = InsertNewInstBefore(new CastInst(Op, I.getType(), "tmp"), I);
|
||||
return new ShiftInst(I.getOpcode(), Op,
|
||||
ShiftInst* ShiftResult = new ShiftInst(I.getOpcode(), Op,
|
||||
ConstantInt::get(Type::UByteTy, Amt));
|
||||
if (I.getType() == ShiftResult->getType())
|
||||
return ShiftResult;
|
||||
InsertNewInstBefore(ShiftResult, I);
|
||||
return new CastInst(ShiftResult, I.getType());
|
||||
}
|
||||
|
||||
// Check for (A << c1) >> c2 or (A >> c1) << c2. If we are dealing with
|
||||
@ -5265,10 +5249,10 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
||||
if (isLeftShift)
|
||||
C = ConstantExpr::getShl(C, ShiftAmt1C);
|
||||
else
|
||||
C = ConstantExpr::getUShr(C, ShiftAmt1C);
|
||||
C = ConstantExpr::getLShr(C, ShiftAmt1C);
|
||||
|
||||
Value *Op = ShiftOp->getOperand(0);
|
||||
if (isShiftOfSignedShift != isSignedShift)
|
||||
if (Op->getType() != C->getType())
|
||||
Op = InsertCastBefore(Op, I.getType(), I);
|
||||
|
||||
Instruction *Mask =
|
||||
@ -5283,14 +5267,8 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
|
||||
} else if (isShiftOfUnsignedShift || isShiftOfLeftShift) {
|
||||
if (isShiftOfUnsignedShift && !isShiftOfLeftShift && isSignedShift) {
|
||||
// Make sure to emit an unsigned shift right, not a signed one.
|
||||
Mask = InsertNewInstBefore(new CastInst(Mask,
|
||||
Mask->getType()->getUnsignedVersion(),
|
||||
Op->getName()), I);
|
||||
Mask = new ShiftInst(Instruction::Shr, Mask,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
|
||||
InsertNewInstBefore(Mask, I);
|
||||
return new CastInst(Mask, I.getType());
|
||||
return new ShiftInst(Instruction::LShr, Mask,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
|
||||
} else {
|
||||
return new ShiftInst(ShiftOp->getOpcode(), Mask,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
|
||||
@ -5792,7 +5770,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
||||
case Instruction::Shl:
|
||||
// Allow changing the sign of the source operand. Do not allow changing
|
||||
// the size of the shift, UNLESS the shift amount is a constant. We
|
||||
// mush not change variable sized shifts to a smaller size, because it
|
||||
// must not change variable sized shifts to a smaller size, because it
|
||||
// is undefined to shift more bits out than exist in the value.
|
||||
if (DestBitSize == SrcBitSize ||
|
||||
(DestBitSize < SrcBitSize && isa<Constant>(Op1))) {
|
||||
@ -5800,21 +5778,16 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
||||
return new ShiftInst(Instruction::Shl, Op0c, Op1);
|
||||
}
|
||||
break;
|
||||
case Instruction::Shr:
|
||||
case Instruction::AShr:
|
||||
// If this is a signed shr, and if all bits shifted in are about to be
|
||||
// truncated off, turn it into an unsigned shr to allow greater
|
||||
// simplifications.
|
||||
if (DestBitSize < SrcBitSize && Src->getType()->isSigned() &&
|
||||
if (DestBitSize < SrcBitSize &&
|
||||
isa<ConstantInt>(Op1)) {
|
||||
unsigned ShiftAmt = cast<ConstantInt>(Op1)->getZExtValue();
|
||||
if (SrcBitSize > ShiftAmt && SrcBitSize-ShiftAmt >= DestBitSize) {
|
||||
// Convert to unsigned.
|
||||
Value *N1 = InsertOperandCastBefore(Op0,
|
||||
Op0->getType()->getUnsignedVersion(), &CI);
|
||||
// Insert the new shift, which is now unsigned.
|
||||
N1 = InsertNewInstBefore(new ShiftInst(Instruction::Shr, N1,
|
||||
Op1, Src->getName()), CI);
|
||||
return new CastInst(N1, CI.getType());
|
||||
// Insert the new logical shift right.
|
||||
return new ShiftInst(Instruction::LShr, Op0, Op1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -5853,13 +5826,9 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
|
||||
unsigned ShiftAmt = Log2_64(KnownZero^TypeMask);
|
||||
Value *In = Op0;
|
||||
if (ShiftAmt) {
|
||||
// Perform an unsigned shr by shiftamt. Convert input to
|
||||
// unsigned if it is signed.
|
||||
if (In->getType()->isSigned())
|
||||
In = InsertCastBefore(
|
||||
In, In->getType()->getUnsignedVersion(), CI);
|
||||
// Perform a logical shr by shiftamt.
|
||||
// Insert the shift to put the result in the low bit.
|
||||
In = InsertNewInstBefore(new ShiftInst(Instruction::Shr, In,
|
||||
In = InsertNewInstBefore(new ShiftInst(Instruction::LShr, In,
|
||||
ConstantInt::get(Type::UByteTy, ShiftAmt),
|
||||
In->getName()+".lobit"), CI);
|
||||
}
|
||||
@ -5934,7 +5903,8 @@ static unsigned GetSelectFoldableOperands(Instruction *I) {
|
||||
return 3; // Can fold through either operand.
|
||||
case Instruction::Sub: // Can only fold on the amount subtracted.
|
||||
case Instruction::Shl: // Can only fold on the shift amount.
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
return 1;
|
||||
default:
|
||||
return 0; // Cannot fold
|
||||
@ -5952,7 +5922,8 @@ static Constant *GetSelectFoldableConstant(Instruction *I) {
|
||||
case Instruction::Xor:
|
||||
return Constant::getNullValue(I->getType());
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
return Constant::getNullValue(Type::UByteTy);
|
||||
case Instruction::And:
|
||||
return ConstantInt::getAllOnesValue(I->getType());
|
||||
@ -6125,7 +6096,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
||||
// this by inserting a new SRA.
|
||||
unsigned Bits = X->getType()->getPrimitiveSizeInBits();
|
||||
Constant *ShAmt = ConstantInt::get(Type::UByteTy, Bits-1);
|
||||
Instruction *SRA = new ShiftInst(Instruction::Shr, X,
|
||||
Instruction *SRA = new ShiftInst(Instruction::AShr, X,
|
||||
ShAmt, "ones");
|
||||
InsertNewInstBefore(SRA, SI);
|
||||
|
||||
|
@ -617,10 +617,11 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) {
|
||||
} else {
|
||||
if (Offset) {
|
||||
assert(NV->getType()->isInteger() && "Unknown promotion!");
|
||||
if (Offset < TD.getTypeSize(NV->getType())*8)
|
||||
NV = new ShiftInst(Instruction::Shr, NV,
|
||||
ConstantInt::get(Type::UByteTy, Offset),
|
||||
if (Offset < TD.getTypeSize(NV->getType())*8) {
|
||||
NV = new ShiftInst(Instruction::LShr, NV,
|
||||
ConstantInt::get(Type::UByteTy, Offset),
|
||||
LI->getName(), LI);
|
||||
}
|
||||
} else {
|
||||
assert((NV->getType()->isInteger() ||
|
||||
isa<PointerType>(NV->getType())) && "Unknown promotion!");
|
||||
|
@ -120,7 +120,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opc, const Type *DestTy,
|
||||
}
|
||||
return 0;
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
return ConstantExpr::get(Opc, Ops[0], Ops[1]);
|
||||
case Instruction::Cast:
|
||||
return ConstantExpr::getCast(Ops[0], DestTy);
|
||||
|
@ -368,7 +368,8 @@ static bool DominatesMergePoint(Value *V, BasicBlock *BB,
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
case Instruction::SetEQ:
|
||||
case Instruction::SetNE:
|
||||
case Instruction::SetLT:
|
||||
|
@ -50,7 +50,8 @@ namespace {
|
||||
virtual Constant *op_or (const Constant *V1, const Constant *V2) const = 0;
|
||||
virtual Constant *op_xor(const Constant *V1, const Constant *V2) const = 0;
|
||||
virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
|
||||
virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
|
||||
virtual Constant *lshr(const Constant *V1, const Constant *V2) const = 0;
|
||||
virtual Constant *ashr(const Constant *V1, const Constant *V2) const = 0;
|
||||
virtual Constant *lessthan(const Constant *V1, const Constant *V2) const =0;
|
||||
virtual Constant *equalto(const Constant *V1, const Constant *V2) const = 0;
|
||||
|
||||
@ -140,8 +141,11 @@ class VISIBILITY_HIDDEN TemplateRules : public ConstRules {
|
||||
virtual Constant *shl(const Constant *V1, const Constant *V2) const {
|
||||
return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);
|
||||
}
|
||||
virtual Constant *shr(const Constant *V1, const Constant *V2) const {
|
||||
return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);
|
||||
virtual Constant *lshr(const Constant *V1, const Constant *V2) const {
|
||||
return SubClassName::LShr((const ArgType *)V1, (const ArgType *)V2);
|
||||
}
|
||||
virtual Constant *ashr(const Constant *V1, const Constant *V2) const {
|
||||
return SubClassName::AShr((const ArgType *)V1, (const ArgType *)V2);
|
||||
}
|
||||
|
||||
virtual Constant *lessthan(const Constant *V1, const Constant *V2) const {
|
||||
@ -207,7 +211,8 @@ class VISIBILITY_HIDDEN TemplateRules : public ConstRules {
|
||||
static Constant *Or (const ArgType *V1, const ArgType *V2) { return 0; }
|
||||
static Constant *Xor (const ArgType *V1, const ArgType *V2) { return 0; }
|
||||
static Constant *Shl (const ArgType *V1, const ArgType *V2) { return 0; }
|
||||
static Constant *Shr (const ArgType *V1, const ArgType *V2) { return 0; }
|
||||
static Constant *LShr(const ArgType *V1, const ArgType *V2) { return 0; }
|
||||
static Constant *AShr(const ArgType *V1, const ArgType *V2) { return 0; }
|
||||
static Constant *LessThan(const ArgType *V1, const ArgType *V2) {
|
||||
return 0;
|
||||
}
|
||||
@ -420,12 +425,6 @@ struct VISIBILITY_HIDDEN ConstantPackedRules
|
||||
static Constant *Xor(const ConstantPacked *V1, const ConstantPacked *V2) {
|
||||
return EvalVectorOp(V1, V2, ConstantExpr::getXor);
|
||||
}
|
||||
static Constant *Shl(const ConstantPacked *V1, const ConstantPacked *V2) {
|
||||
return EvalVectorOp(V1, V2, ConstantExpr::getShl);
|
||||
}
|
||||
static Constant *Shr(const ConstantPacked *V1, const ConstantPacked *V2) {
|
||||
return EvalVectorOp(V1, V2, ConstantExpr::getShr);
|
||||
}
|
||||
static Constant *LessThan(const ConstantPacked *V1, const ConstantPacked *V2){
|
||||
return 0;
|
||||
}
|
||||
@ -581,9 +580,13 @@ struct VISIBILITY_HIDDEN DirectIntRules
|
||||
return ConstantInt::get(*Ty, R);
|
||||
}
|
||||
|
||||
static Constant *Shr(const ConstantInt *V1, const ConstantInt *V2) {
|
||||
BuiltinType R =
|
||||
(BuiltinType)V1->getZExtValue() >> (BuiltinType)V2->getZExtValue();
|
||||
static Constant *LShr(const ConstantInt *V1, const ConstantInt *V2) {
|
||||
BuiltinType R = BuiltinType(V1->getZExtValue() >> V2->getZExtValue());
|
||||
return ConstantInt::get(*Ty, R);
|
||||
}
|
||||
|
||||
static Constant *AShr(const ConstantInt *V1, const ConstantInt *V2) {
|
||||
BuiltinType R = BuiltinType(V1->getSExtValue() >> V2->getZExtValue());
|
||||
return ConstantInt::get(*Ty, R);
|
||||
}
|
||||
};
|
||||
@ -1278,7 +1281,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
case Instruction::Or: C = ConstRules::get(V1, V2).op_or (V1, V2); break;
|
||||
case Instruction::Xor: C = ConstRules::get(V1, V2).op_xor(V1, V2); break;
|
||||
case Instruction::Shl: C = ConstRules::get(V1, V2).shl(V1, V2); break;
|
||||
case Instruction::Shr: C = ConstRules::get(V1, V2).shr(V1, V2); break;
|
||||
case Instruction::LShr: C = ConstRules::get(V1, V2).lshr(V1, V2); break;
|
||||
case Instruction::AShr: C = ConstRules::get(V1, V2).ashr(V1, V2); break;
|
||||
case Instruction::SetEQ: C = ConstRules::get(V1, V2).equalto(V1, V2); break;
|
||||
case Instruction::SetLT: C = ConstRules::get(V1, V2).lessthan(V1, V2);break;
|
||||
case Instruction::SetGT: C = ConstRules::get(V1, V2).lessthan(V2, V1);break;
|
||||
@ -1366,21 +1370,20 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
return const_cast<Constant*>(V2); // X / undef -> undef
|
||||
case Instruction::Or: // X | undef -> -1
|
||||
return ConstantInt::getAllOnesValue(V1->getType());
|
||||
case Instruction::Shr:
|
||||
if (!isa<UndefValue>(V2)) {
|
||||
if (V1->getType()->isSigned())
|
||||
return const_cast<Constant*>(V1); // undef >>s X -> undef
|
||||
// undef >>u X -> 0
|
||||
} else if (isa<UndefValue>(V1)) {
|
||||
return const_cast<Constant*>(V1); // undef >> undef -> undef
|
||||
} else {
|
||||
if (V1->getType()->isSigned())
|
||||
return const_cast<Constant*>(V1); // X >>s undef -> X
|
||||
}
|
||||
return Constant::getNullValue(V1->getType());// X >>u undef -> 0
|
||||
|
||||
case Instruction::LShr:
|
||||
if (isa<UndefValue>(V2) && isa<UndefValue>(V1))
|
||||
return const_cast<Constant*>(V1); // undef lshr undef -> undef
|
||||
return Constant::getNullValue(V1->getType()); // X lshr undef -> 0
|
||||
// undef lshr X -> 0
|
||||
case Instruction::AShr:
|
||||
if (!isa<UndefValue>(V2))
|
||||
return const_cast<Constant*>(V1); // undef ashr X --> undef
|
||||
else if (isa<UndefValue>(V1))
|
||||
return const_cast<Constant*>(V1); // undef ashr undef -> undef
|
||||
else
|
||||
return const_cast<Constant*>(V1); // X ashr undef --> X
|
||||
case Instruction::Shl:
|
||||
// undef << X -> 0 X << undef -> 0
|
||||
// undef << X -> 0 or X << undef -> 0
|
||||
return Constant::getNullValue(V1->getType());
|
||||
}
|
||||
}
|
||||
@ -1466,7 +1469,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
return ConstantFoldBinaryInstruction(Opcode, V2, V1);
|
||||
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
case Instruction::Sub:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::UDiv:
|
||||
|
@ -498,20 +498,11 @@ Constant *ConstantExpr::getSetGE(Constant *C1, Constant *C2) {
|
||||
Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
|
||||
return get(Instruction::Shl, C1, C2);
|
||||
}
|
||||
Constant *ConstantExpr::getShr(Constant *C1, Constant *C2) {
|
||||
return get(Instruction::Shr, C1, C2);
|
||||
Constant *ConstantExpr::getLShr(Constant *C1, Constant *C2) {
|
||||
return get(Instruction::LShr, C1, C2);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getUShr(Constant *C1, Constant *C2) {
|
||||
if (C1->getType()->isUnsigned()) return getShr(C1, C2);
|
||||
return getCast(getShr(getCast(C1,
|
||||
C1->getType()->getUnsignedVersion()), C2), C1->getType());
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getSShr(Constant *C1, Constant *C2) {
|
||||
if (C1->getType()->isSigned()) return getShr(C1, C2);
|
||||
return getCast(getShr(getCast(C1,
|
||||
C1->getType()->getSignedVersion()), C2), C1->getType());
|
||||
Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2) {
|
||||
return get(Instruction::AShr, C1, C2);
|
||||
}
|
||||
|
||||
/// getWithOperandReplaced - Return a constant expression identical to this
|
||||
@ -1330,7 +1321,9 @@ namespace llvm {
|
||||
return new UnaryConstantExpr(Instruction::Cast, V.second[0], Ty);
|
||||
if ((V.first >= Instruction::BinaryOpsBegin &&
|
||||
V.first < Instruction::BinaryOpsEnd) ||
|
||||
V.first == Instruction::Shl || V.first == Instruction::Shr)
|
||||
V.first == Instruction::Shl ||
|
||||
V.first == Instruction::LShr ||
|
||||
V.first == Instruction::AShr)
|
||||
return new BinaryConstantExpr(V.first, V.second[0], V.second[1]);
|
||||
if (V.first == Instruction::Select)
|
||||
return new SelectConstantExpr(V.second[0], V.second[1], V.second[2]);
|
||||
@ -1364,7 +1357,8 @@ namespace llvm {
|
||||
OldC->getOperand(2));
|
||||
break;
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
New = ConstantExpr::getShiftTy(NewTy, OldC->getOpcode(),
|
||||
OldC->getOperand(0), OldC->getOperand(1));
|
||||
break;
|
||||
@ -1453,7 +1447,8 @@ Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {
|
||||
|
||||
Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
|
||||
Constant *C1, Constant *C2) {
|
||||
if (Opcode == Instruction::Shl || Opcode == Instruction::Shr)
|
||||
if (Opcode == Instruction::Shl || Opcode == Instruction::LShr ||
|
||||
Opcode == Instruction::AShr)
|
||||
return getShiftTy(ReqTy, Opcode, C1, C2);
|
||||
// Check the operands for consistency first
|
||||
assert(Opcode >= Instruction::BinaryOpsBegin &&
|
||||
@ -1521,9 +1516,10 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
|
||||
assert(C1->getType() == C2->getType() && "Op types should be identical!");
|
||||
break;
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:
|
||||
assert(C2->getType() == Type::UByteTy && "Shift should be by ubyte!");
|
||||
assert((C1->getType()->isInteger() || isa<PackedType>(C1->getType())) &&
|
||||
assert(C1->getType()->isInteger() &&
|
||||
"Tried to create a shift operation on a non-integer type!");
|
||||
break;
|
||||
default:
|
||||
@ -1558,8 +1554,9 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
|
||||
Constant *ConstantExpr::getShiftTy(const Type *ReqTy, unsigned Opcode,
|
||||
Constant *C1, Constant *C2) {
|
||||
// Check the operands for consistency first
|
||||
assert((Opcode == Instruction::Shl ||
|
||||
Opcode == Instruction::Shr) &&
|
||||
assert((Opcode == Instruction::Shl ||
|
||||
Opcode == Instruction::LShr ||
|
||||
Opcode == Instruction::AShr) &&
|
||||
"Invalid opcode in binary constant expression");
|
||||
assert(C1->getType()->isIntegral() && C2->getType() == Type::UByteTy &&
|
||||
"Invalid operand types for Shift constant expr!");
|
||||
|
@ -128,7 +128,8 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
|
||||
case Select: return "select";
|
||||
case Call: return "call";
|
||||
case Shl: return "shl";
|
||||
case Shr: return "shr";
|
||||
case LShr: return "lshr";
|
||||
case AShr: return "ashr";
|
||||
case VAArg: return "va_arg";
|
||||
case ExtractElement: return "extractelement";
|
||||
case InsertElement: return "insertelement";
|
||||
|
@ -1222,17 +1222,6 @@ bool BinaryOperator::swapOperands() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ShiftInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// isLogicalShift - Return true if this is a logical shift left or a logical
|
||||
/// shift right.
|
||||
bool ShiftInst::isLogicalShift() const {
|
||||
return getOpcode() == Instruction::Shl || getType()->isUnsigned();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CastInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1257,7 +1257,7 @@ StackerCompiler::handle_word( int tkn )
|
||||
LoadInst* op2 = cast<LoadInst>(pop_integer(bb));
|
||||
CastInst* castop = new CastInst( op1, Type::UByteTy );
|
||||
bb->getInstList().push_back( castop );
|
||||
ShiftInst* shrop = new ShiftInst( Instruction::Shr, op2, castop );
|
||||
ShiftInst* shrop = new ShiftInst( Instruction::AShr, op2, castop );
|
||||
bb->getInstList().push_back( shrop );
|
||||
push_value( bb, shrop );
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llvm-as < %s | opt -instcombine -disable-output &&
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep 'shr int'
|
||||
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 'lshr int'
|
||||
|
||||
int %test0(int %X, ubyte %A) {
|
||||
%Y = shr int %X, ubyte %A ; can be logical shift.
|
||||
|
@ -788,7 +788,8 @@ void CppWriter::printConstant(const Constant *CV) {
|
||||
case Instruction::SetLT: Out << "getSetLT"; break;
|
||||
case Instruction::SetGT: Out << "getSetGT"; break;
|
||||
case Instruction::Shl: Out << "getShl"; break;
|
||||
case Instruction::Shr: Out << "getShr"; break;
|
||||
case Instruction::LShr: Out << "getLShr"; break;
|
||||
case Instruction::AShr: Out << "getAShr"; break;
|
||||
case Instruction::Select: Out << "getSelect"; break;
|
||||
case Instruction::ExtractElement: Out << "getExtractElement"; break;
|
||||
case Instruction::InsertElement: Out << "getInsertElement"; break;
|
||||
@ -1034,7 +1035,8 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname) {
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:{
|
||||
case Instruction::LShr:
|
||||
case Instruction::AShr:{
|
||||
Out << "BinaryOperator* " << iName << " = BinaryOperator::create(";
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::Add: Out << "Instruction::Add"; break;
|
||||
@ -1050,7 +1052,8 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname) {
|
||||
case Instruction::Or: Out << "Instruction::Or"; break;
|
||||
case Instruction::Xor: Out << "Instruction::Xor"; break;
|
||||
case Instruction::Shl: Out << "Instruction::Shl"; break;
|
||||
case Instruction::Shr: Out << "Instruction::Shr"; break;
|
||||
case Instruction::LShr:Out << "Instruction::LShr"; break;
|
||||
case Instruction::AShr:Out << "Instruction::AShr"; break;
|
||||
default: Out << "Instruction::BadOpCode"; break;
|
||||
}
|
||||
Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
|
||||
|
Loading…
Reference in New Issue
Block a user