add support for alignment attributes on load/store instructions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36301 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Christopher Lamb 2007-04-21 08:16:25 +00:00
parent 1b7f584fd8
commit 2330e4d4c4
19 changed files with 3486 additions and 4367 deletions

View File

@ -118,6 +118,10 @@ N: Sumant Kowshik
E: kowshik@uiuc.edu E: kowshik@uiuc.edu
D: Author of the original C backend D: Author of the original C backend
N: Christopher Lamb
E: christopher.lamb@gmail.com
D: aligned load/store support
N: Jim Laskey N: Jim Laskey
E: jlaskey@apple.com E: jlaskey@apple.com
D: Improvements to the PPC backend, instruction scheduling D: Improvements to the PPC backend, instruction scheduling

View File

@ -1587,15 +1587,15 @@ possible. </p>
<tr><td>Call+FastCC+TailCall</td><td>59</td><td>5</td><td>1.5</td></tr> <tr><td>Call+FastCC+TailCall</td><td>59</td><td>5</td><td>1.5</td></tr>
<tr><td>Call+FastCC</td><td>60</td><td>5</td><td>1.5</td></tr> <tr><td>Call+FastCC</td><td>60</td><td>5</td><td>1.5</td></tr>
<tr><td>Call+CCC+TailCall</td><td>61</td><td>5</td><td>1.5</td></tr> <tr><td>Call+CCC+TailCall</td><td>61</td><td>5</td><td>1.5</td></tr>
<tr><td>Load+Volatile</td><td>62</td><td>3</td><td>1.3</td></tr> <tr><td>Load+Attributes</td><td>62</td><td>7</td><td>2.0</td></tr>
<tr><td>Store+Volatile</td><td>63</td><td>3</td><td>1.3</td></tr> <tr><td>Store+Attributes</td><td>63</td><td>7</td><td>2.0</td></tr>
</tbody> </tbody>
</table> </table>
<p><b><a name="pi_note">* Note: </a></b> <p><b><a name="pi_note">* Note: </a></b>
These aren't really opcodes from an LLVM language perspective. They encode These aren't really opcodes from an LLVM language perspective. They encode
information into other opcodes without reserving space for that information. information into other opcodes without reserving space for that information.
For example, opcode=63 is a Volatile Store. The opcode for this For example, opcode=63 is an Attributed Store. The opcode for this
instruction is 25 (Store) but we encode it as 63 to indicate that is a Volatile instruction is 25 (Store) but we encode it as 63 to indicate that is a Volatile
Store. The same is done for the calling conventions and tail calls. Store. The same is done for the calling conventions and tail calls.
In each of these entries in range 56-63, the opcode is documented as the base In each of these entries in range 56-63, the opcode is documented as the base

View File

@ -2609,7 +2609,7 @@ instructions), the memory is reclaimed.</p>
Instruction</a> </div> Instruction</a> </div>
<div class="doc_text"> <div class="doc_text">
<h5>Syntax:</h5> <h5>Syntax:</h5>
<pre> &lt;result&gt; = load &lt;ty&gt;* &lt;pointer&gt;<br> &lt;result&gt; = volatile load &lt;ty&gt;* &lt;pointer&gt;<br></pre> <pre> &lt;result&gt; = load &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;]<br> &lt;result&gt; = volatile load &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;]<br></pre>
<h5>Overview:</h5> <h5>Overview:</h5>
<p>The '<tt>load</tt>' instruction is used to read from memory.</p> <p>The '<tt>load</tt>' instruction is used to read from memory.</p>
<h5>Arguments:</h5> <h5>Arguments:</h5>
@ -2634,8 +2634,8 @@ instructions. </p>
Instruction</a> </div> Instruction</a> </div>
<div class="doc_text"> <div class="doc_text">
<h5>Syntax:</h5> <h5>Syntax:</h5>
<pre> store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt; <i>; yields {void}</i> <pre> store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;] <i>; yields {void}</i>
volatile store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt; <i>; yields {void}</i> volatile store &lt;ty&gt; &lt;value&gt;, &lt;ty&gt;* &lt;pointer&gt;[, align &lt;alignment&gt;] <i>; yields {void}</i>
</pre> </pre>
<h5>Overview:</h5> <h5>Overview:</h5>
<p>The '<tt>store</tt>' instruction is used to write to memory.</p> <p>The '<tt>store</tt>' instruction is used to write to memory.</p>

View File

@ -311,10 +311,12 @@ public:
/// determined by their operands, and they produce a value AND a token chain. /// determined by their operands, and they produce a value AND a token chain.
/// ///
SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
const Value *SV, int SVOffset, bool isVolatile=false); const Value *SV, int SVOffset, bool isVolatile=false,
unsigned Alignment=0);
SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT, SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
SDOperand Chain, SDOperand Ptr, const Value *SV, SDOperand Chain, SDOperand Ptr, const Value *SV,
int SVOffset, MVT::ValueType EVT, bool isVolatile=false); int SVOffset, MVT::ValueType EVT, bool isVolatile=false,
unsigned Alignment=0);
SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base, SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
SDOperand Offset, ISD::MemIndexedMode AM); SDOperand Offset, ISD::MemIndexedMode AM);
SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain, SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain,
@ -323,10 +325,11 @@ public:
/// getStore - Helper function to build ISD::STORE nodes. /// getStore - Helper function to build ISD::STORE nodes.
/// ///
SDOperand getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, SDOperand getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr,
const Value *SV, int SVOffset, bool isVolatile=false); const Value *SV, int SVOffset, bool isVolatile=false,
unsigned Alignment=0);
SDOperand getTruncStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, SDOperand getTruncStore(SDOperand Chain, SDOperand Val, SDOperand Ptr,
const Value *SV, int SVOffset, MVT::ValueType TVT, const Value *SV, int SVOffset, MVT::ValueType TVT,
bool isVolatile=false); bool isVolatile=false, unsigned Alignment=0);
SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base, SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base,
SDOperand Offset, ISD::MemIndexedMode AM); SDOperand Offset, ISD::MemIndexedMode AM);

View File

@ -1448,7 +1448,7 @@ protected:
friend class SelectionDAG; friend class SelectionDAG;
LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs, LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
const Value *SV, int O=0, unsigned Align=1, bool Vol=false) const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
: SDNode(ISD::LOAD, VTs), : SDNode(ISD::LOAD, VTs),
AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O), AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O),
Alignment(Align), IsVolatile(Vol) { Alignment(Align), IsVolatile(Vol) {
@ -1456,6 +1456,7 @@ protected:
Ops[1] = ChainPtrOff[1]; // Ptr Ops[1] = ChainPtrOff[1]; // Ptr
Ops[2] = ChainPtrOff[2]; // Off Ops[2] = ChainPtrOff[2]; // Off
InitOperands(Ops, 3); InitOperands(Ops, 3);
assert(Align != 0 && "Loads should have non-zero aligment");
assert((getOffset().getOpcode() == ISD::UNDEF || assert((getOffset().getOpcode() == ISD::UNDEF ||
AddrMode != ISD::UNINDEXED) && AddrMode != ISD::UNINDEXED) &&
"Only indexed load has a non-undef offset operand"); "Only indexed load has a non-undef offset operand");
@ -1518,6 +1519,7 @@ protected:
Ops[2] = ChainValuePtrOff[2]; // Ptr Ops[2] = ChainValuePtrOff[2]; // Ptr
Ops[3] = ChainValuePtrOff[3]; // Off Ops[3] = ChainValuePtrOff[3]; // Off
InitOperands(Ops, 4); InitOperands(Ops, 4);
assert(Align != 0 && "Stores should have non-zero aligment");
assert((getOffset().getOpcode() == ISD::UNDEF || assert((getOffset().getOpcode() == ISD::UNDEF ||
AddrMode != ISD::UNINDEXED) && AddrMode != ISD::UNINDEXED) &&
"Only indexed store has a non-undef offset operand"); "Only indexed store has a non-undef offset operand");

View File

@ -211,9 +211,11 @@ public:
/// SubclassData field in Value to store whether or not the load is volatile. /// SubclassData field in Value to store whether or not the load is volatile.
/// ///
class LoadInst : public UnaryInstruction { class LoadInst : public UnaryInstruction {
LoadInst(const LoadInst &LI) LoadInst(const LoadInst &LI)
: UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) { : UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) {
setVolatile(LI.isVolatile()); setVolatile(LI.isVolatile());
setAlignment(LI.getAlignment());
#ifndef NDEBUG #ifndef NDEBUG
AssertOK(); AssertOK();
@ -225,6 +227,8 @@ public:
LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd);
LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false, LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false,
Instruction *InsertBefore = 0); Instruction *InsertBefore = 0);
LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align,
Instruction *InsertBefore = 0);
LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
BasicBlock *InsertAtEnd); BasicBlock *InsertAtEnd);
@ -238,14 +242,23 @@ public:
/// isVolatile - Return true if this is a load from a volatile memory /// isVolatile - Return true if this is a load from a volatile memory
/// location. /// location.
/// ///
bool isVolatile() const { return SubclassData; } bool isVolatile() const { return SubclassData & 1; }
/// setVolatile - Specify whether this is a volatile load or not. /// setVolatile - Specify whether this is a volatile load or not.
/// ///
void setVolatile(bool V) { SubclassData = V; } void setVolatile(bool V) { SubclassData = (SubclassData & ~1) | (V) ? 1 : 0; }
virtual LoadInst *clone() const; virtual LoadInst *clone() const;
/// getAlignment - Return the alignment of the access that is being performed
///
unsigned getAlignment() const {
signed Log2AlignVal = ((SubclassData>>1)-1);
return ((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal);
}
void setAlignment(unsigned Align);
Value *getPointerOperand() { return getOperand(0); } Value *getPointerOperand() { return getOperand(0); }
const Value *getPointerOperand() const { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); }
static unsigned getPointerOperandIndex() { return 0U; } static unsigned getPointerOperandIndex() { return 0U; }
@ -269,10 +282,13 @@ public:
/// ///
class StoreInst : public Instruction { class StoreInst : public Instruction {
Use Ops[2]; Use Ops[2];
StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) { StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) {
Ops[0].init(SI.Ops[0], this); Ops[0].init(SI.Ops[0], this);
Ops[1].init(SI.Ops[1], this); Ops[1].init(SI.Ops[1], this);
setVolatile(SI.isVolatile()); setVolatile(SI.isVolatile());
setAlignment(SI.getAlignment());
#ifndef NDEBUG #ifndef NDEBUG
AssertOK(); AssertOK();
#endif #endif
@ -283,17 +299,19 @@ public:
StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
Instruction *InsertBefore = 0); Instruction *InsertBefore = 0);
StoreInst(Value *Val, Value *Ptr, bool isVolatile,
unsigned Align, Instruction *InsertBefore = 0);
StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
/// isVolatile - Return true if this is a load from a volatile memory /// isVolatile - Return true if this is a load from a volatile memory
/// location. /// location.
/// ///
bool isVolatile() const { return SubclassData; } bool isVolatile() const { return SubclassData & 1; }
/// setVolatile - Specify whether this is a volatile load or not. /// setVolatile - Specify whether this is a volatile load or not.
/// ///
void setVolatile(bool V) { SubclassData = V; } void setVolatile(bool V) { SubclassData = (SubclassData & ~1) | (V) ? 1 : 0; }
/// Transparently provide more efficient getOperand methods. /// Transparently provide more efficient getOperand methods.
Value *getOperand(unsigned i) const { Value *getOperand(unsigned i) const {
@ -306,6 +324,14 @@ public:
} }
unsigned getNumOperands() const { return 2; } unsigned getNumOperands() const { return 2; }
/// getAlignment - Return the alignment of the access that is being performed
///
unsigned getAlignment() const {
signed Log2AlignVal = ((SubclassData>>1)-1);
return ((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal);
}
void setAlignment(unsigned Align);
virtual StoreInst *clone() const; virtual StoreInst *clone() const;

File diff suppressed because it is too large Load Diff

View File

@ -1,308 +1,4 @@
/* A Bison parser, made by GNU Bison 2.1. */ typedef union {
/* 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,
ESAPINTVAL = 260,
EUAPINTVAL = 261,
LOCALVAL_ID = 262,
GLOBALVAL_ID = 263,
FPVAL = 264,
VOID = 265,
INTTYPE = 266,
FLOAT = 267,
DOUBLE = 268,
LABEL = 269,
TYPE = 270,
LOCALVAR = 271,
GLOBALVAR = 272,
LABELSTR = 273,
STRINGCONSTANT = 274,
ATSTRINGCONSTANT = 275,
ZEROINITIALIZER = 276,
TRUETOK = 277,
FALSETOK = 278,
BEGINTOK = 279,
ENDTOK = 280,
DECLARE = 281,
DEFINE = 282,
GLOBAL = 283,
CONSTANT = 284,
SECTION = 285,
VOLATILE = 286,
THREAD_LOCAL = 287,
TO = 288,
DOTDOTDOT = 289,
NULL_TOK = 290,
UNDEF = 291,
INTERNAL = 292,
LINKONCE = 293,
WEAK = 294,
APPENDING = 295,
DLLIMPORT = 296,
DLLEXPORT = 297,
EXTERN_WEAK = 298,
OPAQUE = 299,
EXTERNAL = 300,
TARGET = 301,
TRIPLE = 302,
ALIGN = 303,
DEPLIBS = 304,
CALL = 305,
TAIL = 306,
ASM_TOK = 307,
MODULE = 308,
SIDEEFFECT = 309,
CC_TOK = 310,
CCC_TOK = 311,
FASTCC_TOK = 312,
COLDCC_TOK = 313,
X86_STDCALLCC_TOK = 314,
X86_FASTCALLCC_TOK = 315,
DATALAYOUT = 316,
RET = 317,
BR = 318,
SWITCH = 319,
INVOKE = 320,
UNWIND = 321,
UNREACHABLE = 322,
ADD = 323,
SUB = 324,
MUL = 325,
UDIV = 326,
SDIV = 327,
FDIV = 328,
UREM = 329,
SREM = 330,
FREM = 331,
AND = 332,
OR = 333,
XOR = 334,
SHL = 335,
LSHR = 336,
ASHR = 337,
ICMP = 338,
FCMP = 339,
EQ = 340,
NE = 341,
SLT = 342,
SGT = 343,
SLE = 344,
SGE = 345,
ULT = 346,
UGT = 347,
ULE = 348,
UGE = 349,
OEQ = 350,
ONE = 351,
OLT = 352,
OGT = 353,
OLE = 354,
OGE = 355,
ORD = 356,
UNO = 357,
UEQ = 358,
UNE = 359,
MALLOC = 360,
ALLOCA = 361,
FREE = 362,
LOAD = 363,
STORE = 364,
GETELEMENTPTR = 365,
TRUNC = 366,
ZEXT = 367,
SEXT = 368,
FPTRUNC = 369,
FPEXT = 370,
BITCAST = 371,
UITOFP = 372,
SITOFP = 373,
FPTOUI = 374,
FPTOSI = 375,
INTTOPTR = 376,
PTRTOINT = 377,
PHI_TOK = 378,
SELECT = 379,
VAARG = 380,
EXTRACTELEMENT = 381,
INSERTELEMENT = 382,
SHUFFLEVECTOR = 383,
NORETURN = 384,
INREG = 385,
SRET = 386,
NOUNWIND = 387,
DEFAULT = 388,
HIDDEN = 389
};
#endif
/* Tokens. */
#define ESINT64VAL 258
#define EUINT64VAL 259
#define ESAPINTVAL 260
#define EUAPINTVAL 261
#define LOCALVAL_ID 262
#define GLOBALVAL_ID 263
#define FPVAL 264
#define VOID 265
#define INTTYPE 266
#define FLOAT 267
#define DOUBLE 268
#define LABEL 269
#define TYPE 270
#define LOCALVAR 271
#define GLOBALVAR 272
#define LABELSTR 273
#define STRINGCONSTANT 274
#define ATSTRINGCONSTANT 275
#define ZEROINITIALIZER 276
#define TRUETOK 277
#define FALSETOK 278
#define BEGINTOK 279
#define ENDTOK 280
#define DECLARE 281
#define DEFINE 282
#define GLOBAL 283
#define CONSTANT 284
#define SECTION 285
#define VOLATILE 286
#define THREAD_LOCAL 287
#define TO 288
#define DOTDOTDOT 289
#define NULL_TOK 290
#define UNDEF 291
#define INTERNAL 292
#define LINKONCE 293
#define WEAK 294
#define APPENDING 295
#define DLLIMPORT 296
#define DLLEXPORT 297
#define EXTERN_WEAK 298
#define OPAQUE 299
#define EXTERNAL 300
#define TARGET 301
#define TRIPLE 302
#define ALIGN 303
#define DEPLIBS 304
#define CALL 305
#define TAIL 306
#define ASM_TOK 307
#define MODULE 308
#define SIDEEFFECT 309
#define CC_TOK 310
#define CCC_TOK 311
#define FASTCC_TOK 312
#define COLDCC_TOK 313
#define X86_STDCALLCC_TOK 314
#define X86_FASTCALLCC_TOK 315
#define DATALAYOUT 316
#define RET 317
#define BR 318
#define SWITCH 319
#define INVOKE 320
#define UNWIND 321
#define UNREACHABLE 322
#define ADD 323
#define SUB 324
#define MUL 325
#define UDIV 326
#define SDIV 327
#define FDIV 328
#define UREM 329
#define SREM 330
#define FREM 331
#define AND 332
#define OR 333
#define XOR 334
#define SHL 335
#define LSHR 336
#define ASHR 337
#define ICMP 338
#define FCMP 339
#define EQ 340
#define NE 341
#define SLT 342
#define SGT 343
#define SLE 344
#define SGE 345
#define ULT 346
#define UGT 347
#define ULE 348
#define UGE 349
#define OEQ 350
#define ONE 351
#define OLT 352
#define OGT 353
#define OLE 354
#define OGE 355
#define ORD 356
#define UNO 357
#define UEQ 358
#define UNE 359
#define MALLOC 360
#define ALLOCA 361
#define FREE 362
#define LOAD 363
#define STORE 364
#define GETELEMENTPTR 365
#define TRUNC 366
#define ZEXT 367
#define SEXT 368
#define FPTRUNC 369
#define FPEXT 370
#define BITCAST 371
#define UITOFP 372
#define SITOFP 373
#define FPTOUI 374
#define FPTOSI 375
#define INTTOPTR 376
#define PTRTOINT 377
#define PHI_TOK 378
#define SELECT 379
#define VAARG 380
#define EXTRACTELEMENT 381
#define INSERTELEMENT 382
#define SHUFFLEVECTOR 383
#define NORETURN 384
#define INREG 385
#define SRET 386
#define NOUNWIND 387
#define DEFAULT 388
#define HIDDEN 389
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 938 "/proj/llvm/llvm-2/lib/AsmParser/llvmAsmParser.y"
typedef union YYSTYPE {
llvm::Module *ModuleVal; llvm::Module *ModuleVal;
llvm::Function *FunctionVal; llvm::Function *FunctionVal;
llvm::BasicBlock *BasicBlockVal; llvm::BasicBlock *BasicBlockVal;
@ -348,14 +44,138 @@ typedef union YYSTYPE {
llvm::ICmpInst::Predicate IPredicate; llvm::ICmpInst::Predicate IPredicate;
llvm::FCmpInst::Predicate FPredicate; llvm::FCmpInst::Predicate FPredicate;
} YYSTYPE; } YYSTYPE;
/* Line 1447 of yacc.c. */ #define ESINT64VAL 257
#line 353 "llvmAsmParser.tab.h" #define EUINT64VAL 258
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ #define ESAPINTVAL 259
# define YYSTYPE_IS_DECLARED 1 #define EUAPINTVAL 260
# define YYSTYPE_IS_TRIVIAL 1 #define LOCALVAL_ID 261
#endif #define GLOBALVAL_ID 262
#define FPVAL 263
#define VOID 264
#define INTTYPE 265
#define FLOAT 266
#define DOUBLE 267
#define LABEL 268
#define TYPE 269
#define LOCALVAR 270
#define GLOBALVAR 271
#define LABELSTR 272
#define STRINGCONSTANT 273
#define ATSTRINGCONSTANT 274
#define ZEROINITIALIZER 275
#define TRUETOK 276
#define FALSETOK 277
#define BEGINTOK 278
#define ENDTOK 279
#define DECLARE 280
#define DEFINE 281
#define GLOBAL 282
#define CONSTANT 283
#define SECTION 284
#define VOLATILE 285
#define THREAD_LOCAL 286
#define TO 287
#define DOTDOTDOT 288
#define NULL_TOK 289
#define UNDEF 290
#define INTERNAL 291
#define LINKONCE 292
#define WEAK 293
#define APPENDING 294
#define DLLIMPORT 295
#define DLLEXPORT 296
#define EXTERN_WEAK 297
#define OPAQUE 298
#define EXTERNAL 299
#define TARGET 300
#define TRIPLE 301
#define ALIGN 302
#define DEPLIBS 303
#define CALL 304
#define TAIL 305
#define ASM_TOK 306
#define MODULE 307
#define SIDEEFFECT 308
#define CC_TOK 309
#define CCC_TOK 310
#define FASTCC_TOK 311
#define COLDCC_TOK 312
#define X86_STDCALLCC_TOK 313
#define X86_FASTCALLCC_TOK 314
#define DATALAYOUT 315
#define RET 316
#define BR 317
#define SWITCH 318
#define INVOKE 319
#define UNWIND 320
#define UNREACHABLE 321
#define ADD 322
#define SUB 323
#define MUL 324
#define UDIV 325
#define SDIV 326
#define FDIV 327
#define UREM 328
#define SREM 329
#define FREM 330
#define AND 331
#define OR 332
#define XOR 333
#define SHL 334
#define LSHR 335
#define ASHR 336
#define ICMP 337
#define FCMP 338
#define EQ 339
#define NE 340
#define SLT 341
#define SGT 342
#define SLE 343
#define SGE 344
#define ULT 345
#define UGT 346
#define ULE 347
#define UGE 348
#define OEQ 349
#define ONE 350
#define OLT 351
#define OGT 352
#define OLE 353
#define OGE 354
#define ORD 355
#define UNO 356
#define UEQ 357
#define UNE 358
#define MALLOC 359
#define ALLOCA 360
#define FREE 361
#define LOAD 362
#define STORE 363
#define GETELEMENTPTR 364
#define TRUNC 365
#define ZEXT 366
#define SEXT 367
#define FPTRUNC 368
#define FPEXT 369
#define BITCAST 370
#define UITOFP 371
#define SITOFP 372
#define FPTOUI 373
#define FPTOSI 374
#define INTTOPTR 375
#define PTRTOINT 376
#define PHI_TOK 377
#define SELECT 378
#define VAARG 379
#define EXTRACTELEMENT 380
#define INSERTELEMENT 381
#define SHUFFLEVECTOR 382
#define NORETURN 383
#define INREG 384
#define SRET 385
#define NOUNWIND 386
#define DEFAULT 387
#define HIDDEN 388
extern YYSTYPE llvmAsmlval; extern YYSTYPE llvmAsmlval;

View File

@ -2921,7 +2921,7 @@ MemoryInst : MALLOC Types OptCAlign {
CHECK_FOR_ERROR CHECK_FOR_ERROR
} }
| OptVolatile LOAD Types ValueRef { | OptVolatile LOAD Types ValueRef OptCAlign {
if (!UpRefs.empty()) if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
if (!isa<PointerType>($3->get())) if (!isa<PointerType>($3->get()))
@ -2932,10 +2932,10 @@ MemoryInst : MALLOC Types OptCAlign {
(*$3)->getDescription()); (*$3)->getDescription());
Value* tmpVal = getVal(*$3, $4); Value* tmpVal = getVal(*$3, $4);
CHECK_FOR_ERROR CHECK_FOR_ERROR
$$ = new LoadInst(tmpVal, "", $1); $$ = new LoadInst(tmpVal, "", $1, $5);
delete $3; delete $3;
} }
| OptVolatile STORE ResolvedVal ',' Types ValueRef { | OptVolatile STORE ResolvedVal ',' Types ValueRef OptCAlign {
if (!UpRefs.empty()) if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription());
const PointerType *PT = dyn_cast<PointerType>($5->get()); const PointerType *PT = dyn_cast<PointerType>($5->get());
@ -2949,7 +2949,7 @@ MemoryInst : MALLOC Types OptCAlign {
Value* tmpVal = getVal(*$5, $6); Value* tmpVal = getVal(*$5, $6);
CHECK_FOR_ERROR CHECK_FOR_ERROR
$$ = new StoreInst($3, tmpVal, $1); $$ = new StoreInst($3, tmpVal, $1, $7);
delete $5; delete $5;
} }
| GETELEMENTPTR Types ValueRef IndexList { | GETELEMENTPTR Types ValueRef IndexList {

View File

@ -2921,7 +2921,7 @@ MemoryInst : MALLOC Types OptCAlign {
CHECK_FOR_ERROR CHECK_FOR_ERROR
} }
| OptVolatile LOAD Types ValueRef { | OptVolatile LOAD Types ValueRef OptCAlign {
if (!UpRefs.empty()) if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
if (!isa<PointerType>($3->get())) if (!isa<PointerType>($3->get()))
@ -2932,10 +2932,10 @@ MemoryInst : MALLOC Types OptCAlign {
(*$3)->getDescription()); (*$3)->getDescription());
Value* tmpVal = getVal(*$3, $4); Value* tmpVal = getVal(*$3, $4);
CHECK_FOR_ERROR CHECK_FOR_ERROR
$$ = new LoadInst(tmpVal, "", $1); $$ = new LoadInst(tmpVal, "", $1, $5);
delete $3; delete $3;
} }
| OptVolatile STORE ResolvedVal ',' Types ValueRef { | OptVolatile STORE ResolvedVal ',' Types ValueRef OptCAlign {
if (!UpRefs.empty()) if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription());
const PointerType *PT = dyn_cast<PointerType>($5->get()); const PointerType *PT = dyn_cast<PointerType>($5->get());
@ -2949,7 +2949,7 @@ MemoryInst : MALLOC Types OptCAlign {
Value* tmpVal = getVal(*$5, $6); Value* tmpVal = getVal(*$5, $6);
CHECK_FOR_ERROR CHECK_FOR_ERROR
$$ = new StoreInst($3, tmpVal, $1); $$ = new StoreInst($3, tmpVal, $1, $7);
delete $5; delete $5;
} }
| GETELEMENTPTR Types ValueRef IndexList { | GETELEMENTPTR Types ValueRef IndexList {

View File

@ -831,13 +831,31 @@ void BytecodeReader::ParseInstruction(SmallVector<unsigned, 8> &Oprnds,
&Idx[0], Idx.size()); &Idx[0], Idx.size());
break; break;
} }
case 62: // volatile load case 62: { // attributed load
if (Oprnds.size() != 2 || !isa<PointerType>(InstTy))
error("Invalid attributed load instruction!");
signed Log2AlignVal = ((Oprnds[1]>>1)-1);
Result = new LoadInst(getValue(iType, Oprnds[0]), "", (Oprnds[1] & 1),
((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal));
break;
}
case Instruction::Load: case Instruction::Load:
if (Oprnds.size() != 1 || !isa<PointerType>(InstTy)) if (Oprnds.size() != 1 || !isa<PointerType>(InstTy))
error("Invalid load instruction!"); error("Invalid load instruction!");
Result = new LoadInst(getValue(iType, Oprnds[0]), "", Opcode == 62); Result = new LoadInst(getValue(iType, Oprnds[0]), "");
break; break;
case 63: // volatile store case 63: { // attributed store
if (!isa<PointerType>(InstTy) || Oprnds.size() != 3)
error("Invalid store instruction!");
Value *Ptr = getValue(iType, Oprnds[1]);
const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
signed Log2AlignVal = ((Oprnds[2]>>1)-1);
Result = new StoreInst(getValue(getTypeSlot(ValTy), Oprnds[0]), Ptr,
(Oprnds[2] & 1),
((Log2AlignVal < 0) ? 0 : 1<<Log2AlignVal));
break;
}
case Instruction::Store: { case Instruction::Store: {
if (!isa<PointerType>(InstTy) || Oprnds.size() != 2) if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
error("Invalid store instruction!"); error("Invalid store instruction!");

View File

@ -616,7 +616,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
unsigned Opcode = I.getOpcode(); unsigned Opcode = I.getOpcode();
unsigned NumOperands = I.getNumOperands(); unsigned NumOperands = I.getNumOperands();
// Encode 'tail call' as 61, 'volatile load' as 62, and 'volatile store' as // Encode 'tail call' as 61
// 63. // 63.
if (const CallInst *CI = dyn_cast<CallInst>(&I)) { if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
if (CI->getCallingConv() == CallingConv::C) { if (CI->getCallingConv() == CallingConv::C) {
@ -632,10 +632,6 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
} else { } else {
Opcode = 58; // Call escape sequence. Opcode = 58; // Call escape sequence.
} }
} else if (isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) {
Opcode = 62;
} else if (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile()) {
Opcode = 63;
} }
// Figure out which type to encode with the instruction. Typically we want // Figure out which type to encode with the instruction. Typically we want
@ -744,6 +740,32 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
} else if (isa<InvokeInst>(I)) { } else if (isa<InvokeInst>(I)) {
// Invoke escape seq has at least 4 operands to encode. // Invoke escape seq has at least 4 operands to encode.
++NumOperands; ++NumOperands;
} else if (const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
// Encode attributed load as opcode 62
// We need to encode the attributes of the load instruction as the second
// operand. Its not really a slot, but we don't want to break the
// instruction format for these instructions.
if (LI->getAlignment() || LI->isVolatile()) {
NumOperands = 2;
Slots[1] = ((Log2_32(LI->getAlignment())+1)<<1) +
(LI->isVolatile() ? 1 : 0);
if (Slots[1] > MaxOpSlot)
MaxOpSlot = Slots[1];
Opcode = 62;
}
} else if (const StoreInst *SI = dyn_cast<StoreInst>(&I)) {
// Encode attributed store as opcode 63
// We need to encode the attributes of the store instruction as the third
// operand. Its not really a slot, but we don't want to break the
// instruction format for these instructions.
if (SI->getAlignment() || SI->isVolatile()) {
NumOperands = 3;
Slots[2] = ((Log2_32(SI->getAlignment())+1)<<1) +
(SI->isVolatile() ? 1 : 0);
if (Slots[2] > MaxOpSlot)
MaxOpSlot = Slots[2];
Opcode = 63;
}
} }
// Decide which instruction encoding to use. This is determined primarily // Decide which instruction encoding to use. This is determined primarily

View File

@ -1263,7 +1263,9 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
(!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) { (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
AddToWorkList(N); AddToWorkList(N);
CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
return SDOperand(N, 0); // Return N so it doesn't get rechecked! return SDOperand(N, 0); // Return N so it doesn't get rechecked!
@ -1280,7 +1282,9 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
(!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) { (!AfterLegalize || TLI.isLoadXLegal(ISD::ZEXTLOAD, EVT))) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
AddToWorkList(N); AddToWorkList(N);
CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
return SDOperand(N, 0); // Return N so it doesn't get rechecked! return SDOperand(N, 0); // Return N so it doesn't get rechecked!
@ -1320,7 +1324,8 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
AddToWorkList(NewPtr.Val); AddToWorkList(NewPtr.Val);
SDOperand Load = SDOperand Load =
DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr, DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT); LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
AddToWorkList(N); AddToWorkList(N);
CombineTo(N0.Val, Load, Load.getValue(1)); CombineTo(N0.Val, Load, Load.getValue(1));
return SDOperand(N, 0); // Return N so it doesn't get rechecked! return SDOperand(N, 0); // Return N so it doesn't get rechecked!
@ -2120,7 +2125,8 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), LN0->getSrcValueOffset(),
N0.getValueType()); N0.getValueType(),
LN0->isVolatile());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -2136,7 +2142,9 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
if (!AfterLegalize || TLI.isLoadXLegal(ISD::SEXTLOAD, EVT)) { if (!AfterLegalize || TLI.isLoadXLegal(ISD::SEXTLOAD, EVT)) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -2212,7 +2220,9 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), LN0->getSrcValueOffset(),
N0.getValueType()); N0.getValueType(),
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -2227,7 +2237,9 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
MVT::ValueType EVT = LN0->getLoadedVT(); MVT::ValueType EVT = LN0->getLoadedVT();
SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -2303,7 +2315,9 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), LN0->getSrcValueOffset(),
N0.getValueType()); N0.getValueType(),
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -2321,7 +2335,9 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) {
SDOperand ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), VT, SDOperand ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), VT,
LN0->getChain(), LN0->getBasePtr(), LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -2398,9 +2414,11 @@ SDOperand DAGCombiner::ReduceLoadWidth(SDNode *N) {
AddToWorkList(NewPtr.Val); AddToWorkList(NewPtr.Val);
SDOperand Load = (ExtType == ISD::NON_EXTLOAD) SDOperand Load = (ExtType == ISD::NON_EXTLOAD)
? DAG.getLoad(VT, LN0->getChain(), NewPtr, ? DAG.getLoad(VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset()) LN0->getSrcValue(), LN0->getSrcValueOffset(),
LN0->isVolatile(), LN0->getAlignment())
: DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr, : DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT); LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(), LN0->getAlignment());
AddToWorkList(N); AddToWorkList(N);
if (CombineSRL) { if (CombineSRL) {
std::vector<SDNode*> NowDead; std::vector<SDNode*> NowDead;
@ -2479,7 +2497,9 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0); LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
return SDOperand(N, 0); // Return N so it doesn't get rechecked! return SDOperand(N, 0); // Return N so it doesn't get rechecked!
@ -2492,7 +2512,9 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0); LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), EVT); LN0->getSrcValueOffset(), EVT,
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1)); CombineTo(N0.Val, ExtLoad, ExtLoad.getValue(1));
return SDOperand(N, 0); // Return N so it doesn't get rechecked! return SDOperand(N, 0); // Return N so it doesn't get rechecked!
@ -2552,7 +2574,8 @@ SDOperand DAGCombiner::visitBIT_CONVERT(SDNode *N) {
if (0 && ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse()) { if (0 && ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse()) {
LoadSDNode *LN0 = cast<LoadSDNode>(N0); LoadSDNode *LN0 = cast<LoadSDNode>(N0);
SDOperand Load = DAG.getLoad(VT, LN0->getChain(), LN0->getBasePtr(), SDOperand Load = DAG.getLoad(VT, LN0->getChain(), LN0->getBasePtr(),
LN0->getSrcValue(), LN0->getSrcValueOffset()); LN0->getSrcValue(), LN0->getSrcValueOffset(),
LN0->isVolatile(), LN0->getAlignment());
AddToWorkList(N); AddToWorkList(N);
CombineTo(N0.Val, DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load), CombineTo(N0.Val, DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load),
Load.getValue(1)); Load.getValue(1));
@ -2942,7 +2965,9 @@ SDOperand DAGCombiner::visitFP_EXTEND(SDNode *N) {
SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(), SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(),
LN0->getBasePtr(), LN0->getSrcValue(), LN0->getBasePtr(), LN0->getSrcValue(),
LN0->getSrcValueOffset(), LN0->getSrcValueOffset(),
N0.getValueType()); N0.getValueType(),
LN0->isVolatile(),
LN0->getAlignment());
CombineTo(N, ExtLoad); CombineTo(N, ExtLoad);
CombineTo(N0.Val, DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad), CombineTo(N0.Val, DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad),
ExtLoad.getValue(1)); ExtLoad.getValue(1));
@ -3331,13 +3356,16 @@ SDOperand DAGCombiner::visitLOAD(SDNode *N) {
// Replace the chain to void dependency. // Replace the chain to void dependency.
if (LD->getExtensionType() == ISD::NON_EXTLOAD) { if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr, ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr,
LD->getSrcValue(), LD->getSrcValueOffset()); LD->getSrcValue(), LD->getSrcValueOffset(),
LD->isVolatile(), LD->getAlignment());
} else { } else {
ReplLoad = DAG.getExtLoad(LD->getExtensionType(), ReplLoad = DAG.getExtLoad(LD->getExtensionType(),
LD->getValueType(0), LD->getValueType(0),
BetterChain, Ptr, LD->getSrcValue(), BetterChain, Ptr, LD->getSrcValue(),
LD->getSrcValueOffset(), LD->getSrcValueOffset(),
LD->getLoadedVT()); LD->getLoadedVT(),
LD->isVolatile(),
LD->getAlignment());
} }
// Create token factor to keep old chain connected. // Create token factor to keep old chain connected.
@ -4040,13 +4068,17 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDOperand LHS,
if (LLD->getExtensionType() == ISD::NON_EXTLOAD) if (LLD->getExtensionType() == ISD::NON_EXTLOAD)
Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(), Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(),
Addr,LLD->getSrcValue(), Addr,LLD->getSrcValue(),
LLD->getSrcValueOffset()); LLD->getSrcValueOffset(),
LLD->isVolatile(),
LLD->getAlignment());
else { else {
Load = DAG.getExtLoad(LLD->getExtensionType(), Load = DAG.getExtLoad(LLD->getExtensionType(),
TheSelect->getValueType(0), TheSelect->getValueType(0),
LLD->getChain(), Addr, LLD->getSrcValue(), LLD->getChain(), Addr, LLD->getSrcValue(),
LLD->getSrcValueOffset(), LLD->getSrcValueOffset(),
LLD->getLoadedVT()); LLD->getLoadedVT(),
LLD->isVolatile(),
LLD->getAlignment());
} }
// Users of the select now use the result of the load. // Users of the select now use the result of the load.
CombineTo(TheSelect, Load); CombineTo(TheSelect, Load);

View File

@ -20,6 +20,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
@ -1539,9 +1540,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
SDOperand SelectionDAG::getLoad(MVT::ValueType VT, SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
SDOperand Chain, SDOperand Ptr, SDOperand Chain, SDOperand Ptr,
const Value *SV, int SVOffset, const Value *SV, int SVOffset,
bool isVolatile) { bool isVolatile, unsigned Alignment) {
// FIXME: Alignment == 1 for now.
unsigned Alignment = 1;
SDVTList VTs = getVTList(VT, MVT::Other); SDVTList VTs = getVTList(VT, MVT::Other);
SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType()); SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
SDOperand Ops[] = { Chain, Ptr, Undef }; SDOperand Ops[] = { Chain, Ptr, Undef };
@ -1557,6 +1556,10 @@ SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
void *IP = 0; void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0); return SDOperand(E, 0);
if (Alignment == 0) { // Ensure that codegen never sees alignment 0
const Type *Ty = MVT::getTypeForValueType(VT);
Alignment = TLI.getTargetData()->getABITypeAlignment(Ty);
}
SDNode *N = new LoadSDNode(Ops, VTs, ISD::UNINDEXED, SDNode *N = new LoadSDNode(Ops, VTs, ISD::UNINDEXED,
ISD::NON_EXTLOAD, VT, SV, SVOffset, Alignment, ISD::NON_EXTLOAD, VT, SV, SVOffset, Alignment,
isVolatile); isVolatile);
@ -1569,7 +1572,7 @@ SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
SDOperand Chain, SDOperand Ptr, SDOperand Chain, SDOperand Ptr,
const Value *SV, const Value *SV,
int SVOffset, MVT::ValueType EVT, int SVOffset, MVT::ValueType EVT,
bool isVolatile) { bool isVolatile, unsigned Alignment) {
// If they are asking for an extending load from/to the same thing, return a // If they are asking for an extending load from/to the same thing, return a
// normal load. // normal load.
if (VT == EVT) if (VT == EVT)
@ -1584,8 +1587,6 @@ SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
assert(MVT::isInteger(VT) == MVT::isInteger(EVT) && assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
"Cannot convert from FP to Int or Int -> FP!"); "Cannot convert from FP to Int or Int -> FP!");
// FIXME: Alignment == 1 for now.
unsigned Alignment = 1;
SDVTList VTs = getVTList(VT, MVT::Other); SDVTList VTs = getVTList(VT, MVT::Other);
SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType()); SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
SDOperand Ops[] = { Chain, Ptr, Undef }; SDOperand Ops[] = { Chain, Ptr, Undef };
@ -1601,6 +1602,10 @@ SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
void *IP = 0; void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0); return SDOperand(E, 0);
if (Alignment == 0) { // Ensure that codegen never sees alignment 0
const Type *Ty = MVT::getTypeForValueType(VT);
Alignment = TLI.getTargetData()->getABITypeAlignment(Ty);
}
SDNode *N = new LoadSDNode(Ops, VTs, ISD::UNINDEXED, ExtType, EVT, SDNode *N = new LoadSDNode(Ops, VTs, ISD::UNINDEXED, ExtType, EVT,
SV, SVOffset, Alignment, isVolatile); SV, SVOffset, Alignment, isVolatile);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);
@ -1648,11 +1653,9 @@ SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT,
SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val, SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val,
SDOperand Ptr, const Value *SV, int SVOffset, SDOperand Ptr, const Value *SV, int SVOffset,
bool isVolatile) { bool isVolatile, unsigned Alignment) {
MVT::ValueType VT = Val.getValueType(); MVT::ValueType VT = Val.getValueType();
// FIXME: Alignment == 1 for now.
unsigned Alignment = 1;
SDVTList VTs = getVTList(MVT::Other); SDVTList VTs = getVTList(MVT::Other);
SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType()); SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
SDOperand Ops[] = { Chain, Val, Ptr, Undef }; SDOperand Ops[] = { Chain, Val, Ptr, Undef };
@ -1668,6 +1671,10 @@ SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val,
void *IP = 0; void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0); return SDOperand(E, 0);
if (Alignment == 0) { // Ensure that codegen never sees alignment 0
const Type *Ty = MVT::getTypeForValueType(VT);
Alignment = TLI.getTargetData()->getABITypeAlignment(Ty);
}
SDNode *N = new StoreSDNode(Ops, VTs, ISD::UNINDEXED, false, SDNode *N = new StoreSDNode(Ops, VTs, ISD::UNINDEXED, false,
VT, SV, SVOffset, Alignment, isVolatile); VT, SV, SVOffset, Alignment, isVolatile);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);
@ -1678,7 +1685,7 @@ SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val,
SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val, SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val,
SDOperand Ptr, const Value *SV, SDOperand Ptr, const Value *SV,
int SVOffset, MVT::ValueType SVT, int SVOffset, MVT::ValueType SVT,
bool isVolatile) { bool isVolatile, unsigned Alignment) {
MVT::ValueType VT = Val.getValueType(); MVT::ValueType VT = Val.getValueType();
bool isTrunc = VT != SVT; bool isTrunc = VT != SVT;
@ -1686,8 +1693,6 @@ SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val,
assert(MVT::isInteger(VT) == MVT::isInteger(SVT) && assert(MVT::isInteger(VT) == MVT::isInteger(SVT) &&
"Can't do FP-INT conversion!"); "Can't do FP-INT conversion!");
// FIXME: Alignment == 1 for now.
unsigned Alignment = 1;
SDVTList VTs = getVTList(MVT::Other); SDVTList VTs = getVTList(MVT::Other);
SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType()); SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
SDOperand Ops[] = { Chain, Val, Ptr, Undef }; SDOperand Ops[] = { Chain, Val, Ptr, Undef };
@ -1703,6 +1708,10 @@ SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val,
void *IP = 0; void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0); return SDOperand(E, 0);
if (Alignment == 0) { // Ensure that codegen never sees alignment 0
const Type *Ty = MVT::getTypeForValueType(VT);
Alignment = TLI.getTargetData()->getABITypeAlignment(Ty);
}
SDNode *N = new StoreSDNode(Ops, VTs, ISD::UNINDEXED, isTrunc, SDNode *N = new StoreSDNode(Ops, VTs, ISD::UNINDEXED, isTrunc,
SVT, SV, SVOffset, Alignment, isVolatile); SVT, SV, SVOffset, Alignment, isVolatile);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);

View File

@ -498,7 +498,7 @@ public:
SDOperand getLoadFrom(const Type *Ty, SDOperand Ptr, SDOperand getLoadFrom(const Type *Ty, SDOperand Ptr,
const Value *SV, SDOperand Root, const Value *SV, SDOperand Root,
bool isVolatile); bool isVolatile, unsigned Alignment);
SDOperand getIntPtrConstant(uint64_t Val) { SDOperand getIntPtrConstant(uint64_t Val) {
return DAG.getConstant(Val, TLI.getPointerTy()); return DAG.getConstant(Val, TLI.getPointerTy());
@ -2313,19 +2313,21 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
} }
setValue(&I, getLoadFrom(I.getType(), Ptr, I.getOperand(0), setValue(&I, getLoadFrom(I.getType(), Ptr, I.getOperand(0),
Root, I.isVolatile())); Root, I.isVolatile(), I.getAlignment()));
} }
SDOperand SelectionDAGLowering::getLoadFrom(const Type *Ty, SDOperand Ptr, SDOperand SelectionDAGLowering::getLoadFrom(const Type *Ty, SDOperand Ptr,
const Value *SV, SDOperand Root, const Value *SV, SDOperand Root,
bool isVolatile) { bool isVolatile,
unsigned Alignment) {
SDOperand L; SDOperand L;
if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) { if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) {
MVT::ValueType PVT = TLI.getValueType(PTy->getElementType()); MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
L = DAG.getVecLoad(PTy->getNumElements(), PVT, Root, Ptr, L = DAG.getVecLoad(PTy->getNumElements(), PVT, Root, Ptr,
DAG.getSrcValue(SV)); DAG.getSrcValue(SV));
} else { } else {
L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SV, 0, isVolatile); L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SV, 0,
isVolatile, Alignment);
} }
if (isVolatile) if (isVolatile)
@ -2342,7 +2344,7 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
SDOperand Src = getValue(SrcV); SDOperand Src = getValue(SrcV);
SDOperand Ptr = getValue(I.getOperand(1)); SDOperand Ptr = getValue(I.getOperand(1));
DAG.setRoot(DAG.getStore(getRoot(), Src, Ptr, I.getOperand(1), 0, DAG.setRoot(DAG.getStore(getRoot(), Src, Ptr, I.getOperand(1), 0,
I.isVolatile())); I.isVolatile(), I.getAlignment()));
} }
/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot /// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot

View File

@ -1308,6 +1308,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
} }
} }
// Print post operand alignment for load/store
if (isa<LoadInst>(I) && cast<LoadInst>(I).getAlignment()) {
Out << ", align " << cast<LoadInst>(I).getAlignment();
} else if (isa<StoreInst>(I) && cast<StoreInst>(I).getAlignment()) {
Out << ", align " << cast<StoreInst>(I).getAlignment();
}
printInfoComment(I); printInfoComment(I);
Out << "\n"; Out << "\n";
} }

View File

@ -20,6 +20,7 @@
#include "llvm/ParameterAttributes.h" #include "llvm/ParameterAttributes.h"
#include "llvm/Support/CallSite.h" #include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h" #include "llvm/Support/ConstantRange.h"
#include "llvm/Support/MathExtras.h"
using namespace llvm; using namespace llvm;
unsigned CallSite::getCallingConv() const { unsigned CallSite::getCallingConv() const {
@ -685,6 +686,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) { Load, Ptr, InsertBef) {
setVolatile(false); setVolatile(false);
setAlignment(0);
AssertOK(); AssertOK();
setName(Name); setName(Name);
} }
@ -693,6 +695,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) { Load, Ptr, InsertAE) {
setVolatile(false); setVolatile(false);
setAlignment(0);
AssertOK(); AssertOK();
setName(Name); setName(Name);
} }
@ -702,6 +705,17 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) { Load, Ptr, InsertBef) {
setVolatile(isVolatile); setVolatile(isVolatile);
setAlignment(0);
AssertOK();
setName(Name);
}
LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
unsigned Align, Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) {
setVolatile(isVolatile);
setAlignment(Align);
AssertOK(); AssertOK();
setName(Name); setName(Name);
} }
@ -711,6 +725,7 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) { Load, Ptr, InsertAE) {
setVolatile(isVolatile); setVolatile(isVolatile);
setAlignment(0);
AssertOK(); AssertOK();
setName(Name); setName(Name);
} }
@ -721,6 +736,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, Instruction *InsertBef)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) { Load, Ptr, InsertBef) {
setVolatile(false); setVolatile(false);
setAlignment(0);
AssertOK(); AssertOK();
if (Name && Name[0]) setName(Name); if (Name && Name[0]) setName(Name);
} }
@ -729,6 +745,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAE)
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) { Load, Ptr, InsertAE) {
setVolatile(false); setVolatile(false);
setAlignment(0);
AssertOK(); AssertOK();
if (Name && Name[0]) setName(Name); if (Name && Name[0]) setName(Name);
} }
@ -738,6 +755,7 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertBef) { Load, Ptr, InsertBef) {
setVolatile(isVolatile); setVolatile(isVolatile);
setAlignment(0);
AssertOK(); AssertOK();
if (Name && Name[0]) setName(Name); if (Name && Name[0]) setName(Name);
} }
@ -747,10 +765,15 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
: UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(), : UnaryInstruction(cast<PointerType>(Ptr->getType())->getElementType(),
Load, Ptr, InsertAE) { Load, Ptr, InsertAE) {
setVolatile(isVolatile); setVolatile(isVolatile);
setAlignment(0);
AssertOK(); AssertOK();
if (Name && Name[0]) setName(Name); if (Name && Name[0]) setName(Name);
} }
void LoadInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
SubclassData = (SubclassData & 1) | ((Log2_32(Align)+1)<<1);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// StoreInst Implementation // StoreInst Implementation
@ -770,6 +793,7 @@ StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore)
Ops[0].init(val, this); Ops[0].init(val, this);
Ops[1].init(addr, this); Ops[1].init(addr, this);
setVolatile(false); setVolatile(false);
setAlignment(0);
AssertOK(); AssertOK();
} }
@ -778,6 +802,7 @@ StoreInst::StoreInst(Value *val, Value *addr, BasicBlock *InsertAtEnd)
Ops[0].init(val, this); Ops[0].init(val, this);
Ops[1].init(addr, this); Ops[1].init(addr, this);
setVolatile(false); setVolatile(false);
setAlignment(0);
AssertOK(); AssertOK();
} }
@ -787,6 +812,17 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
Ops[0].init(val, this); Ops[0].init(val, this);
Ops[1].init(addr, this); Ops[1].init(addr, this);
setVolatile(isVolatile); setVolatile(isVolatile);
setAlignment(0);
AssertOK();
}
StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
unsigned Align, Instruction *InsertBefore)
: Instruction(Type::VoidTy, Store, Ops, 2, InsertBefore) {
Ops[0].init(val, this);
Ops[1].init(addr, this);
setVolatile(isVolatile);
setAlignment(Align);
AssertOK(); AssertOK();
} }
@ -796,9 +832,15 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
Ops[0].init(val, this); Ops[0].init(val, this);
Ops[1].init(addr, this); Ops[1].init(addr, this);
setVolatile(isVolatile); setVolatile(isVolatile);
setAlignment(0);
AssertOK(); AssertOK();
} }
void StoreInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
SubclassData = (SubclassData & 1) | ((Log2_32(Align)+1)<<1);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// GetElementPtrInst Implementation // GetElementPtrInst Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -0,0 +1,7 @@
; RUN: llvm-as < %s |& llvm-dis |& grep 'align 1024'
define i32 @test(i32* %arg) {
entry:
%tmp2 = load i32* %arg, align 1024 ; <i32> [#uses=1]
ret i32 %tmp2
}

View File

@ -0,0 +1,7 @@
; RUN: llvm-as < %s |& llvm-dis | grep 'align 1024'
define void @test(i32* %arg) {
entry:
store i32 0, i32* %arg, align 1024
ret void
}