From baldrick at free.fr Mon Sep 7 00:10:00 2009
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 07 Sep 2009 07:10:00 +0200
Subject: [llvm-commits] [llvm] r81126 -
/llvm/trunk/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
In-Reply-To: <6EC1E224-E0DC-445D-BBDB-4A85D2A55106@apple.com>
References: <200909061927.n86JRrb0015006@zion.cs.uiuc.edu>
<6EC1E224-E0DC-445D-BBDB-4A85D2A55106@apple.com>
Message-ID: <4AA495A8.1000503@free.fr>
Hi Evan,
> This seems wrong. Perhaps the switch statement should be something like
> this?
>
> case X86II::MO_NO_FLAG: // No flag.
> break;
> case X86II::MO_PIC_BASE_OFFSET:
> case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
> case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
> // Subtract the pic base.
> NegatedSymbol = GetPICBaseSymbol();
> break;
the value of NegatedSymbol was not being used.
Ciao,
Duncan.
From baldrick at free.fr Mon Sep 7 00:58:26 2009
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 07 Sep 2009 05:58:26 -0000
Subject: [llvm-commits] [llvm] r81144 -
/llvm/trunk/lib/System/Unix/Program.inc
Message-ID: <200909070558.n875wQkW031467@zion.cs.uiuc.edu>
Author: baldrick
Date: Mon Sep 7 00:58:25 2009
New Revision: 81144
URL: http://llvm.org/viewvc/llvm-project?rev=81144&view=rev
Log:
Using a signal handler that does nothing should be
equivalent to SIG_IGN.
Modified:
llvm/trunk/lib/System/Unix/Program.inc
Modified: llvm/trunk/lib/System/Unix/Program.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Unix/Program.inc?rev=81144&r1=81143&r2=81144&view=diff
==============================================================================
--- llvm/trunk/lib/System/Unix/Program.inc (original)
+++ llvm/trunk/lib/System/Unix/Program.inc Mon Sep 7 00:58:25 2009
@@ -116,9 +116,6 @@
return false;
}
-static void TimeOutHandler(int Sig) {
-}
-
static void SetMemoryLimits (unsigned size)
{
#if HAVE_SYS_RESOURCE_H
@@ -231,10 +228,9 @@
// Install a timeout handler.
if (secondsToWait) {
- Act.sa_sigaction = 0;
- Act.sa_handler = TimeOutHandler;
+ memset(&Act, 0, sizeof(Act));
+ Act.sa_handler = SIG_IGN;
sigemptyset(&Act.sa_mask);
- Act.sa_flags = 0;
sigaction(SIGALRM, &Act, &Old);
alarm(secondsToWait);
}
From baldrick at free.fr Mon Sep 7 00:58:29 2009
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 07 Sep 2009 07:58:29 +0200
Subject: [llvm-commits] [llvm] r81115 - in /llvm/trunk/lib:
CodeGen/RegAllocPBQP.cpp CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
CodeGen/SelectionDAG/SelectionDAGBuild.cpp CodeGen/StackSlotColoring.cpp
Support/regengine.inc System/Unix/Program.inc
Target/ARM/Thumb2SizeReduction.cpp Target/PowerPC/PPCISelLowering.cpp
Target/X86/AsmPrinter/X86MCInstLower.cpp Target/X86/X86ISelLowering.cpp
Target/XCore/XCoreRegisterInfo.cpp Transforms/Scalar/CondPropagate.cpp
In-Reply-To: <04783965-406C-46C4-8CBC-D86443F9FFA3@gmail.com>
References: <200909061241.n86CfKds028484@zion.cs.uiuc.edu>
<04783965-406C-46C4-8CBC-D86443F9FFA3@gmail.com>
Message-ID: <4AA4A105.7000903@free.fr>
Hi Benjamin,
>> MachineFunction::iterator BBI = CR.CaseBB;
>>
>> - if (++BBI != FuncInfo.MF->end())
>> - NextBlock = BBI;
>> + if (++BBI != FuncInfo.MF->end()) {}
>
> This looks weird. I think it can be reduced to
> MachineFunction::iterator BBI = CR.CaseBB + 1;
that turns out to not be equivalent. I changed it to
MachineFunction::iterator BBI = CR.CaseBB + 1;
++BBI;
instead.
>> if (slow(m, sp, rest, ssub, esub) != NULL) {
>> - dp = dissect(m, sp, rest, ssub, esub);
>> + char *dp = dissect(m, sp, rest, ssub, esub);
>> assert(dp == rest);
>
> this change will probably cause "unused variable" warnings in -Asserts
> build
They were unused before too :) However you are right that gcc
understands this now. I have fixed it.
>> --- llvm/trunk/lib/System/Unix/Program.inc (original)
>> +++ llvm/trunk/lib/System/Unix/Program.inc Sun Sep 6 07:41:19 2009
>> @@ -116,9 +116,7 @@
>> return false;
>> }
>>
>> -static bool Timeout = false;
>> static void TimeOutHandler(int Sig) {
>> - Timeout = true;
>> }
>
> It looks like this function can be removed entirely
Now done.
Thanks for thinking about this!
Best wishes,
Duncan.
From baldrick at free.fr Mon Sep 7 03:07:02 2009
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 07 Sep 2009 08:07:02 -0000
Subject: [llvm-commits] [gcc-plugin] r81146 - in /gcc-plugin/trunk:
llvm-backend.cpp llvm-convert.cpp llvm-internal.h
Message-ID: <200909070807.n878724Z028458@zion.cs.uiuc.edu>
Author: baldrick
Date: Mon Sep 7 03:07:02 2009
New Revision: 81146
URL: http://llvm.org/viewvc/llvm-project?rev=81146&view=rev
Log:
Add support for ssa names. I'm not sure I understood
SSA_NAME_IS_DEFAULT_DEF correctly, but this does seem
to work on simple examples. The plugin can now compile
int f(int x) { return x; }
You can't stop progress!
Modified:
gcc-plugin/trunk/llvm-backend.cpp
gcc-plugin/trunk/llvm-convert.cpp
gcc-plugin/trunk/llvm-internal.h
Modified: gcc-plugin/trunk/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-backend.cpp?rev=81146&r1=81145&r2=81146&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-backend.cpp (original)
+++ gcc-plugin/trunk/llvm-backend.cpp Mon Sep 7 03:07:02 2009
@@ -1784,10 +1784,16 @@
// know we want to output it.
DECL_DEFER_OUTPUT(current_function_decl) = 0;
+ // Provide the function convertor with dominators.
+ calculate_dominance_info(CDI_DOMINATORS);
+
// Convert the AST to raw/ugly LLVM code.
TreeToLLVM Emitter(current_function_decl);
Function *Fn = Emitter.EmitFunction();
+ // Free dominator and other ssa data structures.
+ execute_free_datastructures();
+
//TODO performLateBackendInitialization();
createPerFunctionOptimizationPasses();
@@ -1800,8 +1806,6 @@
// Finally, we have written out this function!
TREE_ASM_WRITTEN(current_function_decl) = 1;
- execute_free_datastructures();
-
// When debugging, append the LLVM IR to the dump file.
if (dump_file) {
raw_fd_ostream dump_stream(fileno(dump_file), false);
Modified: gcc-plugin/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-convert.cpp?rev=81146&r1=81145&r2=81146&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-convert.cpp (original)
+++ gcc-plugin/trunk/llvm-convert.cpp Mon Sep 7 03:07:02 2009
@@ -72,6 +72,7 @@
#include "tree-flow.h"
#include "tree-pass.h"
#include "rtl.h"
+#include "domwalk.h"
extern int get_pointer_alignment (tree exp, unsigned int max_align);
extern enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER];
@@ -92,17 +93,6 @@
TREE_CODE(DECL_INITIAL(exp)) == CONSTRUCTOR && \
!TREE_TYPE(DECL_INITIAL(exp)))
-/// isGimpleTemporary - Return true if this is a gimple temporary that we can
-/// directly compile into an LLVM temporary. This saves us from creating an
-/// alloca and creating loads/stores of that alloca (a compile-time win). We
-/// can only do this if the value is a first class llvm value and if it's a
-/// "gimple_formal_tmp_reg".
-static bool isGimpleTemporary(tree decl) {
- return false;
-//FIXME return is_gimple_formal_tmp_reg(decl) &&
-//FIXME !isAggregateTreeType(TREE_TYPE(decl));
-}
-
/// getINTEGER_CSTVal - Return the specified INTEGER_CST value as a uint64_t.
///
uint64_t getINTEGER_CSTVal(tree exp) {
@@ -735,80 +725,83 @@
//TODO // may be deleted when the optimizers run, so would be dangerous to keep.
//TODO eraseLocalLLVMValues();
- // Simplify any values that were uniqued using a no-op bitcast.
- for (std::vector::iterator I = UniquedValues.begin(),
- E = UniquedValues.end(); I != E; ++I) {
- BitCastInst *BI = *I;
- assert(BI->getSrcTy() == BI->getDestTy() && "Not a no-op bitcast!");
- BI->replaceAllUsesWith(BI->getOperand(0));
- // Safe to erase because after the call to eraseLocalLLVMValues.
- BI->eraseFromParent();
- }
- UniquedValues.clear();
-
return Fn;
}
extern "C" tree gimple_to_tree(gimple);
extern "C" void release_stmt_tree (gimple, tree);
-Function *TreeToLLVM::EmitFunction() {
- // Set up parameters and prepare for return, for the function.
- StartFunctionBody();
-
- // Emit the body of the function iterating over all BBs
- basic_block bb;
- edge e;
- edge_iterator ei;
- FOR_EACH_BB (bb) {
- for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
- gsi_next (&gsi)) {
- gimple gimple_stmt = gsi_stmt (gsi);
-
- switch (gimple_code(gimple_stmt)) {
- case GIMPLE_ASSIGN:
- case GIMPLE_COND:
- case GIMPLE_GOTO:
- case GIMPLE_LABEL:
- case GIMPLE_RETURN:
- case GIMPLE_ASM:
- case GIMPLE_CALL:
- case GIMPLE_SWITCH:
- case GIMPLE_NOP:
- case GIMPLE_PREDICT:
- case GIMPLE_RESX: {
- // TODO Handle gimple directly, rather than converting to a tree.
- tree stmt = gimple_to_tree(gimple_stmt);
-
- // If this stmt returns an aggregate value (e.g. a call whose result is
- // ignored), create a temporary to receive the value. Note that we don't
- // do this for MODIFY_EXPRs as an efficiency hack.
- MemRef DestLoc;
- if (isAggregateTreeType(TREE_TYPE(stmt)) &&
- TREE_CODE(stmt)!= MODIFY_EXPR && TREE_CODE(stmt)!=INIT_EXPR)
- DestLoc = CreateTempLoc(ConvertType(TREE_TYPE(stmt)));
+void TreeToLLVM::EmitBasicBlock(basic_block bb) {
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi)) {
+ gimple gimple_stmt = gsi_stmt (gsi);
+
+ switch (gimple_code(gimple_stmt)) {
+ case GIMPLE_ASSIGN:
+ case GIMPLE_COND:
+ case GIMPLE_GOTO:
+ case GIMPLE_LABEL:
+ case GIMPLE_RETURN:
+ case GIMPLE_ASM:
+ case GIMPLE_CALL:
+ case GIMPLE_SWITCH:
+ case GIMPLE_NOP:
+ case GIMPLE_PREDICT:
+ case GIMPLE_RESX: {
+ // TODO Handle gimple directly, rather than converting to a tree.
+ tree stmt = gimple_to_tree(gimple_stmt);
+
+ // If this stmt returns an aggregate value (e.g. a call whose result is
+ // ignored), create a temporary to receive the value. Note that we don't
+ // do this for MODIFY_EXPRs as an efficiency hack.
+ MemRef DestLoc;
+ if (isAggregateTreeType(TREE_TYPE(stmt)) &&
+ TREE_CODE(stmt)!= MODIFY_EXPR && TREE_CODE(stmt)!=INIT_EXPR)
+ DestLoc = CreateTempLoc(ConvertType(TREE_TYPE(stmt)));
- Emit(stmt, DestLoc.Ptr ? &DestLoc : NULL);
-
- release_stmt_tree(gimple_stmt, stmt);
- break;
- }
+ Emit(stmt, DestLoc.Ptr ? &DestLoc : NULL);
- default:
- print_gimple_stmt(stderr, gimple_stmt, 0, TDF_RAW);
- llvm_report_error("Unhandled GIMPLE statement during LLVM emission!");
- }
+ release_stmt_tree(gimple_stmt, stmt);
+ break;
}
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_FALLTHRU)
- break;
- if (e && e->dest != bb->next_bb) {
- Builder.CreateBr(getLabelDeclBlock(gimple_block_label (e->dest)));
- EmitBlock(BasicBlock::Create(Context, ""));
+ default:
+ print_gimple_stmt(stderr, gimple_stmt, 0, TDF_RAW);
+ llvm_unreachable("Unhandled GIMPLE statement during LLVM emission!");
}
}
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+ if (e && e->dest != bb->next_bb) {
+ Builder.CreateBr(getLabelDeclBlock(gimple_block_label (e->dest)));
+ EmitBlock(BasicBlock::Create(Context, ""));
+ }
+}
+
+static void emit_basic_block(struct dom_walk_data *walk_data, basic_block bb) {
+ ((TreeToLLVM *)walk_data->global_data)->EmitBasicBlock(bb);
+}
+
+Function *TreeToLLVM::EmitFunction() {
+ // Set up parameters and prepare for return, for the function.
+ StartFunctionBody();
+
+ // Emit the body of the function by iterating over all BBs. To ensure that
+ // definitions of ssa names are seen before any uses, the iteration is done
+ // in dominator order.
+ struct dom_walk_data walk_data;
+ memset(&walk_data, 0, sizeof(struct dom_walk_data));
+ walk_data.dom_direction = CDI_DOMINATORS;
+ walk_data.before_dom_children = emit_basic_block;
+ walk_data.global_data = this;
+ init_walk_dominator_tree(&walk_data);
+ walk_dominator_tree(&walk_data, ENTRY_BLOCK_PTR);
+ fini_walk_dominator_tree(&walk_data);
+
// Wrap things up.
return FinishFunctionBody();
}
@@ -832,12 +825,8 @@
switch (TREE_CODE(exp)) {
default:
- DEBUG({
- llvm::errs() << "Unhandled expression!\n"
- << "TREE_CODE: " << TREE_CODE(exp) << "\n";
- debug_tree(exp);
- });
- abort();
+ debug_tree(exp);
+ llvm_unreachable("Unhandled expression!");
// Control flow
case LABEL_EXPR: Result = EmitLABEL_EXPR(exp); break;
@@ -852,6 +841,8 @@
case RESX_EXPR: Result = EmitRESX_EXPR(exp); break;
// Expressions
+ case SSA_NAME:
+ Result = EmitSSA_NAME(exp); break;
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
@@ -1030,11 +1021,8 @@
switch (TREE_CODE(exp)) {
default:
- DEBUG({
- errs() << "Unhandled lvalue expression!\n";
- debug_tree(exp);
- });
- abort();
+ debug_tree(exp);
+ llvm_unreachable("Unhandled lvalue expression!");
case PARM_DECL:
case VAR_DECL:
@@ -1115,9 +1103,8 @@
//===----------------------------------------------------------------------===//
void TreeToLLVM::TODO(tree exp) {
- DEBUG(errs() << "Unhandled tree node\n");
if (exp) debug_tree(exp);
- abort();
+ llvm_unreachable("Unhandled tree node");
}
/// CastToType - Cast the specified value to the specified type if it is
@@ -1582,11 +1569,6 @@
TREE_STATIC(decl) || DECL_EXTERNAL(decl) || type == error_mark_node)
return;
- // Gimple temporaries are handled specially: their DECL_LLVM is set when the
- // definition is encountered.
- if (isGimpleTemporary(decl))
- return;
-
// If this is just the rotten husk of a variable that the gimplifier
// eliminated all uses of, but is preserving for debug info, ignore it.
if (TREE_CODE(decl) == VAR_DECL && DECL_VALUE_EXPR(decl))
@@ -2248,30 +2230,22 @@
return false;
}
+/// EmitSSA_NAME - Return the defining value of the given SSA_NAME.
+Value *TreeToLLVM::EmitSSA_NAME(tree exp) {
+ if (SSA_NAME_IS_DEFAULT_DEF(exp))
+ return Emit(SSA_NAME_VAR(exp), 0);
+ return SSANames[exp];
+}
/// EmitLoadOfLValue - When an l-value expression is used in a context that
/// requires an r-value, this method emits the lvalue computation, then loads
/// the result.
Value *TreeToLLVM::EmitLoadOfLValue(tree exp, const MemRef *DestLoc) {
- // If this is a gimple temporary, don't emit a load, just use the result.
- if (isGimpleTemporary(exp)) {
- if (DECL_LLVM_SET_P(exp))
- return DECL_LLVM(exp);
- // Since basic blocks are output in no particular order, it is perfectly
- // possible to encounter a use of a gimple temporary before encountering
- // its definition, which is what has happened here. This happens rarely
- // in practice, so there's no point in trying to do anything clever: just
- // demote to an ordinary variable and create an alloca to hold its value.
-abort(); //FIXME
-//FIXME DECL_GIMPLE_FORMAL_TEMP_P(exp) = 0;
- EmitAutomaticVariableDecl(exp);
- // Fall through.
- } else if (canEmitRegisterVariable(exp)) {
+ if (canEmitRegisterVariable(exp))
// If this is a register variable, EmitLV can't handle it (there is no
// l-value of a register variable). Emit an inline asm node that copies the
// value out of the specified register.
return EmitReadOfRegisterVariable(exp, DestLoc);
- }
LValue LV = EmitLV(exp);
bool isVolatile = TREE_THIS_VOLATILE(exp);
@@ -2868,70 +2842,6 @@
return 0;
}
-/// HandleMultiplyDefinedGimpleTemporary - Gimple temporaries *mostly* have a
-/// single definition, in which case all uses are dominated by the definition.
-/// This routine exists to handle the rare case of a gimple temporary with
-/// multiple definitions. It turns the temporary into an ordinary automatic
-/// variable by creating an alloca for it, initializing the alloca with the
-/// first definition that was seen, and fixing up any existing uses to load
-/// the alloca instead.
-///
-void TreeToLLVM::HandleMultiplyDefinedGimpleTemporary(tree Var) {
- Value *UniqVal = DECL_LLVM(Var);
- assert(isa(UniqVal) && "Invalid value for gimple temporary!");
- Value *FirstVal = cast(UniqVal)->getOperand(0);
-
- // Create a new temporary and set the VAR_DECL to use it as the llvm location.
- Value *NewTmp = CreateTemporary(FirstVal->getType());
- SET_DECL_LLVM(Var, NewTmp);
-
- // Store the already existing initial value into the alloca. If the value
- // being stored is an instruction, emit the store right after the instruction,
- // otherwise, emit it into the entry block.
- StoreInst *SI = new StoreInst(FirstVal, NewTmp);
-
- BasicBlock::iterator InsertPt;
- if (Instruction *I = dyn_cast(FirstVal)) {
- InsertPt = I; // Insert after the init instruction.
-
- // If the instruction is an alloca in the entry block, the insert point
- // will be before the alloca. Advance to the AllocaInsertionPoint if we are
- // before it.
- if (I->getParent() == &Fn->front()) {
- for (BasicBlock::iterator CI = InsertPt, E = Fn->begin()->end();
- CI != E; ++CI) {
- if (&*CI == AllocaInsertionPoint) {
- InsertPt = AllocaInsertionPoint;
- ++InsertPt;
- break;
- }
- }
- }
-
- // If the instruction is an invoke, the init is inserted on the normal edge.
- if (InvokeInst *II = dyn_cast(I)) {
- InsertPt = II->getNormalDest()->begin();
- while (isa(InsertPt))
- ++InsertPt;
- } else
- ++InsertPt; // Insert after the init instruction.
- } else {
- InsertPt = AllocaInsertionPoint; // Insert after the allocas.
- ++InsertPt;
- }
- BasicBlock *BB = InsertPt->getParent();
- BB->getInstList().insert(InsertPt, SI);
-
- // Replace any uses of the original value with a load of the alloca.
- for (Value::use_iterator U = UniqVal->use_begin(), E = UniqVal->use_end();
- U != E; ++U)
- U.getUse().set(new LoadInst(NewTmp, "mtmp", cast(*U)));
-
- // Finally, This is no longer a GCC temporary.
-abort(); //FIXME
-//FIXME DECL_GIMPLE_FORMAL_TEMP_P(Var) = 0;
-}
-
/// EmitMODIFY_EXPR - Note that MODIFY_EXPRs are rvalues only!
/// We also handle INIT_EXPRs here; these are built by the C++ FE on rare
/// occasions, and have slightly different semantics that don't affect us here.
@@ -2940,29 +2850,15 @@
tree lhs = TREE_OPERAND (exp, 0);
tree rhs = TREE_OPERAND (exp, 1);
- // If this is the definition of a gimple temporary, set its DECL_LLVM to the
- // RHS.
bool LHSSigned = !TYPE_UNSIGNED(TREE_TYPE(lhs));
bool RHSSigned = !TYPE_UNSIGNED(TREE_TYPE(rhs));
- if (isGimpleTemporary(lhs)) {
- // If DECL_LLVM is already set, this is a multiply defined gimple temporary.
- if (DECL_LLVM_SET_P(lhs)) {
- HandleMultiplyDefinedGimpleTemporary(lhs);
- return EmitMODIFY_EXPR(exp, DestLoc);
- }
+
+ // If this is the definition of an ssa name, record it in the SSANames map.
+ if (TREE_CODE(lhs) == SSA_NAME) {
+ assert(SSANames.find(lhs) == SSANames.end() && "Multiply defined ssa name!");
Value *RHS = Emit(rhs, 0);
- const Type *LHSTy = ConvertType(TREE_TYPE(lhs));
- // The value may need to be replaced later if this temporary is multiply
- // defined - ensure it can be uniquely identified by not folding the cast.
- Instruction::CastOps opc = CastInst::getCastOpcode(RHS, RHSSigned,
- LHSTy, LHSSigned);
- CastInst *Cast = CastInst::Create(opc, RHS, LHSTy, RHS->getName());
- if (opc == Instruction::BitCast && RHS->getType() == LHSTy)
- // Simplify this no-op bitcast once the function is emitted.
- UniquedValues.push_back(cast(Cast));
- Builder.Insert(Cast);
- SET_DECL_LLVM(lhs, Cast);
- return Cast;
+ SSANames[lhs] = RHS;
+ return RHS;
} else if (canEmitRegisterVariable(lhs)) {
// If this is a store to a register variable, EmitLV can't handle the dest
// (there is no l-value of a register variable). Emit an inline asm node
@@ -6801,9 +6697,6 @@
}
}
- assert(!isGimpleTemporary(exp) &&
- "Cannot use a gimple temporary as an l-value");
-
Value *Decl = DECL_LLVM(exp);
if (Decl == 0) {
if (errorcount || sorrycount) {
Modified: gcc-plugin/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-internal.h?rev=81146&r1=81145&r2=81146&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-internal.h (original)
+++ gcc-plugin/trunk/llvm-internal.h Mon Sep 7 03:07:02 2009
@@ -30,6 +30,7 @@
// LLVM headers
#include "llvm/CallingConv.h"
#include "llvm/Intrinsics.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SetVector.h"
@@ -322,10 +323,9 @@
// AllocaInsertionPoint - Place to insert alloca instructions. Lazily created
// and managed by CreateTemporary.
Instruction *AllocaInsertionPoint;
-
- /// UniquedValues - Values defined using a no-op bitcast in order to make them
- /// unique. These can be simplified once the function has been emitted.
- std::vector UniquedValues;
+
+ // SSANames - Map from GCC ssa names to the defining LLVM value.
+ DenseMap SSANames;
//===---------------------- Exception Handling --------------------------===//
@@ -377,7 +377,10 @@
/// EmitFunction - Convert 'fndecl' to LLVM code.
Function *EmitFunction();
-
+
+ /// EmitBasicBlock - Convert the given basic block.
+ void EmitBasicBlock(basic_block bb);
+
/// EmitLV - Convert the specified l-value tree node to LLVM code, returning
/// the address of the result.
LValue EmitLV(tree_node *exp);
@@ -511,6 +514,7 @@
Value *EmitSWITCH_EXPR(tree_node *exp);
// Expressions.
+ Value *EmitSSA_NAME(tree_node *exp);
Value *EmitLoadOfLValue(tree_node *exp, const MemRef *DestLoc);
Value *EmitOBJ_TYPE_REF(tree_node *exp, const MemRef *DestLoc);
Value *EmitADDR_EXPR(tree_node *exp);
From baldrick at free.fr Mon Sep 7 06:59:55 2009
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 07 Sep 2009 11:59:55 -0000
Subject: [llvm-commits] [gcc-plugin] r81148 - in /gcc-plugin/trunk:
llvm-convert.cpp llvm-internal.h
Message-ID: <200909071159.n87Bxtc5026449@zion.cs.uiuc.edu>
Author: baldrick
Date: Mon Sep 7 06:59:54 2009
New Revision: 81148
URL: http://llvm.org/viewvc/llvm-project?rev=81148&view=rev
Log:
Handle SSA default definitions in a more sophisticated way.
These represent the initial value of a variable at the start
of the function. The only non-trivial case occurs for function
parameters. In this case, associate the ssa name with an explicit
load of the parameter value at an appropriate place in the entry
block.
Modified:
gcc-plugin/trunk/llvm-convert.cpp
gcc-plugin/trunk/llvm-internal.h
Modified: gcc-plugin/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-convert.cpp?rev=81148&r1=81147&r2=81148&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-convert.cpp (original)
+++ gcc-plugin/trunk/llvm-convert.cpp Mon Sep 7 06:59:54 2009
@@ -618,6 +618,13 @@
Args = Args == static_chain ? DECL_ARGUMENTS(FnDecl) : TREE_CHAIN(Args);
}
+ // Loading the value of a PARM_DECL at this point yields its initial value.
+ // Remember this for use when materializing the reads implied by SSA default
+ // definitions.
+ SSAInsertionPoint = Builder.Insert(CastInst::Create(Instruction::BitCast,
+ Constant::getNullValue(Type::getInt32Ty(Context)),
+ Type::getInt32Ty(Context)), "ssa point");
+
// If this is not a void-returning function, initialize the RESULT_DECL.
if (DECL_RESULT(FnDecl) && !VOID_TYPE_P(TREE_TYPE(DECL_RESULT(FnDecl))) &&
!DECL_LLVM_SET_P(DECL_RESULT(FnDecl)))
@@ -2232,9 +2239,42 @@
/// EmitSSA_NAME - Return the defining value of the given SSA_NAME.
Value *TreeToLLVM::EmitSSA_NAME(tree exp) {
- if (SSA_NAME_IS_DEFAULT_DEF(exp))
- return Emit(SSA_NAME_VAR(exp), 0);
- return SSANames[exp];
+ DenseMap::iterator I = SSANames.find(exp);
+ if (I != SSANames.end())
+ return I->second;
+
+ // This SSA name is the default definition for the underlying symbol.
+ assert(SSA_NAME_IS_DEFAULT_DEF(exp) && "SSA name used before being defined!");
+
+ // The underlying symbol is an SSA variable.
+ tree var = SSA_NAME_VAR(exp);
+ assert(SSA_VAR_P(var) && "Not an SSA variable!");
+
+ // If the variable is itself an ssa name, use its LLVM value.
+ if (TREE_CODE (var) == SSA_NAME)
+ return SSANames[exp] = EmitSSA_NAME(var);
+
+ // Otherwise the symbol is a VAR_DECL, PARM_DECL or RESULT_DECL. Since a
+ // default definition is only created if the very first reference to the
+ // variable in the function is a read operation, and refers to the value
+ // read, it has an undefined value except for PARM_DECLs.
+ if (TREE_CODE(var) != PARM_DECL)
+ return UndefValue::get(ConvertType(TREE_TYPE(exp)));
+
+ // Read the initial value of the parameter and associate it with the ssa name.
+ assert(DECL_LLVM_IF_SET(var) && "Parameter not laid out?");
+
+ unsigned Alignment = DECL_ALIGN(var);
+ assert(Alignment != 0 && "Parameter with unknown alignment!");
+
+ const Type *Ty = ConvertType(TREE_TYPE(exp));
+ Value *Ptr = BitCastToType(DECL_LLVM_IF_SET(var), PointerType::getUnqual(Ty));
+
+ // Perform the load in the entry block, after all parameters have been set up
+ // with their initial values, and before any modifications to their values.
+ LoadInst *LI = new LoadInst(Ptr, "defaultdef", SSAInsertionPoint);
+ LI->setAlignment(Alignment);
+ return SSANames[exp] = LI;
}
/// EmitLoadOfLValue - When an l-value expression is used in a context that
@@ -2855,10 +2895,8 @@
// If this is the definition of an ssa name, record it in the SSANames map.
if (TREE_CODE(lhs) == SSA_NAME) {
- assert(SSANames.find(lhs) == SSANames.end() && "Multiply defined ssa name!");
- Value *RHS = Emit(rhs, 0);
- SSANames[lhs] = RHS;
- return RHS;
+ assert(SSANames.find(lhs) == SSANames.end() && "Multiply defined SSA name!");
+ return SSANames[lhs] = Emit(rhs, 0);
} else if (canEmitRegisterVariable(lhs)) {
// If this is a store to a register variable, EmitLV can't handle the dest
// (there is no l-value of a register variable). Emit an inline asm node
Modified: gcc-plugin/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-internal.h?rev=81148&r1=81147&r2=81148&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-internal.h (original)
+++ gcc-plugin/trunk/llvm-internal.h Mon Sep 7 06:59:54 2009
@@ -324,6 +324,10 @@
// and managed by CreateTemporary.
Instruction *AllocaInsertionPoint;
+ // SSAInsertionPoint - Place to insert reads corresponding to SSA default
+ // definitions.
+ Instruction *SSAInsertionPoint;
+
// SSANames - Map from GCC ssa names to the defining LLVM value.
DenseMap SSANames;
From baldrick at free.fr Mon Sep 7 07:23:50 2009
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 07 Sep 2009 12:23:50 -0000
Subject: [llvm-commits] [gcc-plugin] r81149 -
/gcc-plugin/trunk/llvm-convert.cpp
Message-ID: <200909071223.n87CNpI4029623@zion.cs.uiuc.edu>
Author: baldrick
Date: Mon Sep 7 07:23:50 2009
New Revision: 81149
URL: http://llvm.org/viewvc/llvm-project?rev=81149&view=rev
Log:
Name the ssa variable after the parameter name.
This makes the IR a lot more readable.
Modified:
gcc-plugin/trunk/llvm-convert.cpp
Modified: gcc-plugin/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-convert.cpp?rev=81149&r1=81148&r2=81149&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-convert.cpp (original)
+++ gcc-plugin/trunk/llvm-convert.cpp Mon Sep 7 07:23:50 2009
@@ -2267,12 +2267,15 @@
unsigned Alignment = DECL_ALIGN(var);
assert(Alignment != 0 && "Parameter with unknown alignment!");
+ const char *ParameterName =
+ DECL_NAME(var) ? IDENTIFIER_POINTER(DECL_NAME(var)) : "anon";
+
const Type *Ty = ConvertType(TREE_TYPE(exp));
Value *Ptr = BitCastToType(DECL_LLVM_IF_SET(var), PointerType::getUnqual(Ty));
// Perform the load in the entry block, after all parameters have been set up
// with their initial values, and before any modifications to their values.
- LoadInst *LI = new LoadInst(Ptr, "defaultdef", SSAInsertionPoint);
+ LoadInst *LI = new LoadInst(Ptr, ParameterName, SSAInsertionPoint);
LI->setAlignment(Alignment);
return SSANames[exp] = LI;
}
From ssen at apple.com Mon Sep 7 13:46:46 2009
From: ssen at apple.com (Shantonu Sen)
Date: Mon, 7 Sep 2009 11:46:46 -0700
Subject: [llvm-commits] [PATCH] Remove obsolete autoconf stuff,
and upgrade autoconf, cuts down configure size to 361K (from 1.1M!)
In-Reply-To: <6a8523d60909061449u5ce9b254t9a6398e5e313f4ee@mail.gmail.com>
References: <4AA26CD9.10007@gmail.com>
<6a8523d60909061449u5ce9b254t9a6398e5e313f4ee@mail.gmail.com>
Message-ID: <70A73AA7-DF18-44A6-B773-AC05DDDEEB6D@apple.com>
This patch looks scary to me. Do we really want to invest in moving to
a new autoconf/libtool/automake version that I'm told has known
incompatibilities (which means it's unlikely to be used by anyone else)?
Some specific issues:
1)
> dnl Indicate that we require autoconf 2.59 or later. Ths is needed
> because we
> dnl use some autoconf macros only available in 2.59.
> -AC_PREREQ(2.59)
> +AC_PREREQ(2.64)
Please update the comments
2)
> -want_libtool_version='1\.5\.22'
What version of libtool is being used? I can't figure it out. Where is
it documented?
3)
> 3. Copy /ltdl.m4 to llvm/autoconf/m4
> + 3. Copy /ltsugar.m4 to llvm/autoconf/m4
> 4. Copy /share/aclocal/libtool.m4 to llvm/autoconf/m4/
> libtool.m4
You didn't update any of the step numbering, leading to many duplicate
numbered steps and gaps of steps.
4) I thought the policy was not to upgrade config.guess? Even if not,
you've lost several local LLVM changes:
> *:Darwin:*:*)
> UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
> case $UNAME_PROCESSOR in
> - *86) UNAME_PROCESSOR=i686 ;;
> unknown) UNAME_PROCESSOR=powerpc ;;
> esac
I don't know what else was overwritten, but it can't be good.
6) These changes use libtool internal macros, like
"_LT_PROG_ECHO_BACKSLASH". These are not stable, and should not be
used by configure scripts.
I think this requirements more refinement.
Shantonu
Sent from my MacBook
On Sep 6, 2009, at 2:49 PM, Daniel Dunbar wrote:
> 2009/9/5 T?r?k Edwin :
>> Hi,
>>
>> The attached patches update the autoconf stuff to work with latest
>> autoconf, and remove some obsolete m4 macros
>> that were no longer used.
>>
>> This cuts down the size of configure from 1.1M to 361K!
>
> Very nice!
>
>> Can someone test if this works on darwin too?
>
> Seems to work fine, I tested targeting i386/x86_64 and ppc from a
> x86_64-apple-darwin10 machine.
>
>> How should I commit the patch (broken up in 5 pieces or a single
>> commit?)
>
> No opinion.
>
> - Daniel
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From ssen at apple.com Mon Sep 7 13:50:48 2009
From: ssen at apple.com (Shantonu Sen)
Date: Mon, 7 Sep 2009 11:50:48 -0700
Subject: [llvm-commits] [PATCH] x86_64 detection and building on 10.6
In-Reply-To: <9C42BEC1-E380-4E85-BCC5-BA86B7B0E958@apple.com>
References: <638514FD-A5C8-407C-B5F7-778283024822@fallingsnow.net>
<44B13E8C-5C13-47AB-9F45-B07E1ECAAD30@apple.com>
<6a8523d60909020936w23b9606eiba293613499cf4a4@mail.gmail.com>
<72AC7ED1-5507-4076-873D-EC7D9A1B0458@apple.com>
<9C42BEC1-E380-4E85-BCC5-BA86B7B0E958@apple.com>
Message-ID: <7DB11730-EEF6-45CD-86F2-CF2DDD40FF9A@apple.com>
Case in point. Had this change been already committed, it would have
been overwritten by:
I don't think LLVM should be going out on a limb until there's a
reasonable safeguard that local changes won't regress. So far the
evidence is that this type of change would regress within days
Shantonu
Sent from my MacBook
On Sep 2, 2009, at 1:04 PM, Mike Stump wrote:
> On Sep 2, 2009, at 9:41 AM, Shantonu Sen wrote:
>> Isn't config.guess upstream from FSF? Do we really want to fork
>> this file?
>
> No. The upstream is presently getting this support as well through
> other channels. This isn't a fork, but a preview of what is to
> come. When their tree gets it, and it is refreshened through the
> usual updates, eventually we'll get it for free. We should not be
> shy about `fixing' it now.
From daniel at zuster.org Mon Sep 7 14:25:54 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 07 Sep 2009 19:25:54 -0000
Subject: [llvm-commits] [llvm] r81152 - in /llvm/trunk/test:
FrontendC/2009-03-09-WeakDeclarations-1.c lib/llvm.exp
Message-ID: <200909071925.n87JPsHD019177@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Sep 7 14:25:54 2009
New Revision: 81152
URL: http://llvm.org/viewvc/llvm-project?rev=81152&view=rev
Log:
Avoid Tcl substitution, introduced %llvmgcc_only for this one little test
(%llvmgcc includes a '-w' argument, and this test looks for warnings).
Modified:
llvm/trunk/test/FrontendC/2009-03-09-WeakDeclarations-1.c
llvm/trunk/test/lib/llvm.exp
Modified: llvm/trunk/test/FrontendC/2009-03-09-WeakDeclarations-1.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendC/2009-03-09-WeakDeclarations-1.c?rev=81152&r1=81151&r2=81152&view=diff
==============================================================================
--- llvm/trunk/test/FrontendC/2009-03-09-WeakDeclarations-1.c (original)
+++ llvm/trunk/test/FrontendC/2009-03-09-WeakDeclarations-1.c Mon Sep 7 14:25:54 2009
@@ -1,4 +1,4 @@
-// RUN: $llvmgcc $test -c -o /dev/null |& \
+// RUN: %llvmgcc_only %s -c -o /dev/null |& \
// RUN: egrep {(14|15|22): warning:} | \
// RUN: wc -l | grep --quiet 3
// XTARGET: darwin,linux
Modified: llvm/trunk/test/lib/llvm.exp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lib/llvm.exp?rev=81152&r1=81151&r2=81152&view=diff
==============================================================================
--- llvm/trunk/test/lib/llvm.exp (original)
+++ llvm/trunk/test/lib/llvm.exp Mon Sep 7 14:25:54 2009
@@ -59,6 +59,8 @@
regsub -all {%%} $new_line {_#MARKER#_} new_line
#replace %prcontext with prcontext.tcl (Must replace before %p)
regsub -all {%prcontext} $new_line $prcontext new_line
+ #replace %llvmgcc_only with actual path to llvmgcc
+ regsub -all {%llvmgcc_only} $new_line "$llvmgcc" new_line
#replace %llvmgcc with actual path to llvmgcc
regsub -all {%llvmgcc} $new_line "$llvmgcc -emit-llvm -w" new_line
#replace %llvmgxx with actual path to llvmg++
From daniel at zuster.org Mon Sep 7 14:26:03 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 07 Sep 2009 19:26:03 -0000
Subject: [llvm-commits] [llvm] r81153 - in
/llvm/trunk/test/Transforms/InstCombine: 2008-01-06-BitCastAttributes.ll
call.ll
Message-ID: <200909071926.n87JQ3Mq019205@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Sep 7 14:26:02 2009
New Revision: 81153
URL: http://llvm.org/viewvc/llvm-project?rev=81153&view=rev
Log:
Don't depend on Tcl behavior of redirecting stderr for all commands in a
pipeline.
Modified:
llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll
llvm/trunk/test/Transforms/InstCombine/call.ll
Modified: llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll?rev=81153&r1=81152&r2=81153&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/2008-01-06-BitCastAttributes.ll Mon Sep 7 14:26:02 2009
@@ -1,5 +1,5 @@
; Ignore stderr, we expect warnings there
-; RUN: llvm-as < %s 2> /dev/null | opt -instcombine | llvm-dis | not grep bitcast
+; RUN: llvm-as < %s | opt -instcombine 2> /dev/null | llvm-dis | not grep bitcast
define void @a() {
ret void
Modified: llvm/trunk/test/Transforms/InstCombine/call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/call.ll?rev=81153&r1=81152&r2=81153&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/call.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/call.ll Mon Sep 7 14:26:02 2009
@@ -1,5 +1,5 @@
; Ignore stderr, we expect warnings there
-; RUN: llvm-as < %s 2> /dev/null | opt -instcombine | llvm-dis | \
+; RUN: llvm-as < %s | opt -instcombine 2> /dev/null | llvm-dis | \
; RUN: grep call | notcast
; END.
From daniel at zuster.org Mon Sep 7 14:26:11 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 07 Sep 2009 19:26:11 -0000
Subject: [llvm-commits] [llvm] r81154 - in /llvm/trunk/tools/bugpoint:
ExecutionDriver.cpp ExtractFunction.cpp Miscompilation.cpp
OptimizerDriver.cpp
Message-ID: <200909071926.n87JQBmH019236@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Sep 7 14:26:11 2009
New Revision: 81154
URL: http://llvm.org/viewvc/llvm-project?rev=81154&view=rev
Log:
Add -output-prefix option to bugpoint (to change the default output name).
Modified:
llvm/trunk/tools/bugpoint/ExecutionDriver.cpp
llvm/trunk/tools/bugpoint/ExtractFunction.cpp
llvm/trunk/tools/bugpoint/Miscompilation.cpp
llvm/trunk/tools/bugpoint/OptimizerDriver.cpp
Modified: llvm/trunk/tools/bugpoint/ExecutionDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExecutionDriver.cpp?rev=81154&r1=81153&r2=81154&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/ExecutionDriver.cpp (original)
+++ llvm/trunk/tools/bugpoint/ExecutionDriver.cpp Mon Sep 7 14:26:11 2009
@@ -100,6 +100,10 @@
cl::list
InputArgv("args", cl::Positional, cl::desc("..."),
cl::ZeroOrMore, cl::PositionalEatsArgs);
+
+ cl::opt
+ OutputPrefix("output-prefix", cl::init("bugpoint"),
+ cl::desc("Prefix to use for outputs (default: 'bugpoint')"));
}
namespace {
@@ -274,7 +278,7 @@
///
void BugDriver::compileProgram(Module *M) {
// Emit the program to a bitcode file...
- sys::Path BitcodeFile ("bugpoint-test-program.bc");
+ sys::Path BitcodeFile (OutputPrefix + "-test-program.bc");
std::string ErrMsg;
if (BitcodeFile.makeUnique(true,&ErrMsg)) {
errs() << ToolName << ": Error making unique filename: " << ErrMsg
@@ -310,7 +314,7 @@
std::string ErrMsg;
if (BitcodeFile.empty()) {
// Emit the program to a bitcode file...
- sys::Path uniqueFilename("bugpoint-test-program.bc");
+ sys::Path uniqueFilename(OutputPrefix + "-test-program.bc");
if (uniqueFilename.makeUnique(true, &ErrMsg)) {
errs() << ToolName << ": Error making unique filename: "
<< ErrMsg << "!\n";
@@ -330,7 +334,7 @@
sys::Path BitcodePath (BitcodeFile);
FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps);
- if (OutputFile.empty()) OutputFile = "bugpoint-execution-output";
+ if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output";
// Check to see if this is a valid output filename...
sys::Path uniqueFile(OutputFile);
Modified: llvm/trunk/tools/bugpoint/ExtractFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ExtractFunction.cpp?rev=81154&r1=81153&r2=81154&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/ExtractFunction.cpp (original)
+++ llvm/trunk/tools/bugpoint/ExtractFunction.cpp Mon Sep 7 14:26:11 2009
@@ -37,6 +37,7 @@
namespace llvm {
bool DisableSimplifyCFG = false;
+ extern cl::opt OutputPrefix;
} // End llvm namespace
namespace {
@@ -324,7 +325,7 @@
Module *M) {
char *ExtraArg = NULL;
- sys::Path uniqueFilename("bugpoint-extractblocks");
+ sys::Path uniqueFilename(OutputPrefix + "-extractblocks");
std::string ErrMsg;
if (uniqueFilename.createTemporaryFileOnDisk(true, &ErrMsg)) {
outs() << "*** Basic Block extraction failed!\n";
Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=81154&r1=81153&r2=81154&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original)
+++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Mon Sep 7 14:26:11 2009
@@ -30,6 +30,7 @@
using namespace llvm;
namespace llvm {
+ extern cl::opt OutputPrefix;
extern cl::list InputArgv;
}
@@ -301,12 +302,15 @@
<< " Please report a bug!\n";
errs() << " Continuing on with un-loop-extracted version.\n";
- BD.writeProgramToFile("bugpoint-loop-extract-fail-tno.bc", ToNotOptimize);
- BD.writeProgramToFile("bugpoint-loop-extract-fail-to.bc", ToOptimize);
- BD.writeProgramToFile("bugpoint-loop-extract-fail-to-le.bc",
+ BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-tno.bc",
+ ToNotOptimize);
+ BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to.bc",
+ ToOptimize);
+ BD.writeProgramToFile(OutputPrefix + "-loop-extract-fail-to-le.bc",
ToOptimizeLoopExtracted);
- errs() << "Please submit the bugpoint-loop-extract-fail-*.bc files.\n";
+ errs() << "Please submit the "
+ << OutputPrefix << "-loop-extract-fail-*.bc files.\n";
delete ToOptimize;
delete ToNotOptimize;
delete ToOptimizeLoopExtracted;
Modified: llvm/trunk/tools/bugpoint/OptimizerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/OptimizerDriver.cpp?rev=81154&r1=81153&r2=81154&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/OptimizerDriver.cpp (original)
+++ llvm/trunk/tools/bugpoint/OptimizerDriver.cpp Mon Sep 7 14:26:11 2009
@@ -37,6 +37,9 @@
#include
using namespace llvm;
+namespace llvm {
+ extern cl::opt OutputPrefix;
+}
namespace {
// ChildOutput - This option captures the name of the child output file that
@@ -68,7 +71,7 @@
// Output the input to the current pass to a bitcode file, emit a message
// telling the user how to reproduce it: opt -foo blah.bc
//
- std::string Filename = "bugpoint-" + ID + ".bc";
+ std::string Filename = OutputPrefix + "-" + ID + ".bc";
if (writeProgramToFile(Filename)) {
errs() << "Error opening file '" << Filename << "' for writing!\n";
return;
@@ -129,7 +132,7 @@
const char * const *ExtraArgs) const {
// setup the output file name
outs().flush();
- sys::Path uniqueFilename("bugpoint-output.bc");
+ sys::Path uniqueFilename(OutputPrefix + "-output.bc");
std::string ErrMsg;
if (uniqueFilename.makeUnique(true, &ErrMsg)) {
errs() << getToolName() << ": Error making unique filename: "
@@ -139,7 +142,7 @@
OutputFilename = uniqueFilename.str();
// set up the input file name
- sys::Path inputFilename("bugpoint-input.bc");
+ sys::Path inputFilename(OutputPrefix + "-input.bc");
if (inputFilename.makeUnique(true, &ErrMsg)) {
errs() << getToolName() << ": Error making unique filename: "
<< ErrMsg << "\n";
From daniel at zuster.org Mon Sep 7 14:26:18 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 07 Sep 2009 19:26:18 -0000
Subject: [llvm-commits] [llvm] r81155 - in /llvm/trunk/test/BugPoint:
crash-narrowfunctiontest.ll remove_arguments_test.ll
Message-ID: <200909071926.n87JQJ6A019264@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Sep 7 14:26:18 2009
New Revision: 81155
URL: http://llvm.org/viewvc/llvm-project?rev=81155&view=rev
Log:
Use -output-prefix in bugpoint tests so that outputs go in temp directory (and
we don't race on them).
Modified:
llvm/trunk/test/BugPoint/crash-narrowfunctiontest.ll
llvm/trunk/test/BugPoint/remove_arguments_test.ll
Modified: llvm/trunk/test/BugPoint/crash-narrowfunctiontest.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/BugPoint/crash-narrowfunctiontest.ll?rev=81155&r1=81154&r2=81155&view=diff
==============================================================================
--- llvm/trunk/test/BugPoint/crash-narrowfunctiontest.ll (original)
+++ llvm/trunk/test/BugPoint/crash-narrowfunctiontest.ll Mon Sep 7 14:26:18 2009
@@ -1,6 +1,6 @@
; Test that bugpoint can narrow down the testcase to the important function
;
-; RUN: bugpoint %s -bugpoint-crashcalls -silence-passes > /dev/null
+; RUN: bugpoint %s -output-prefix %t -bugpoint-crashcalls -silence-passes > /dev/null
define i32 @foo() { ret i32 1 }
Modified: llvm/trunk/test/BugPoint/remove_arguments_test.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/BugPoint/remove_arguments_test.ll?rev=81155&r1=81154&r2=81155&view=diff
==============================================================================
--- llvm/trunk/test/BugPoint/remove_arguments_test.ll (original)
+++ llvm/trunk/test/BugPoint/remove_arguments_test.ll Mon Sep 7 14:26:18 2009
@@ -1,4 +1,4 @@
-; RUN: bugpoint %s -bugpoint-crashcalls -silence-passes
+; RUN: bugpoint %s -output-prefix %t -bugpoint-crashcalls -silence-passes
; Test to make sure that arguments are removed from the function if they are
; unnecessary.
From edwintorok at gmail.com Mon Sep 7 14:59:19 2009
From: edwintorok at gmail.com (=?ISO-8859-1?Q?T=F6r=F6k_Edwin?=)
Date: Mon, 07 Sep 2009 22:59:19 +0300
Subject: [llvm-commits] [PATCH] Remove obsolete autoconf stuff,
and upgrade autoconf, cuts down configure size to 361K (from 1.1M!)
In-Reply-To: <70A73AA7-DF18-44A6-B773-AC05DDDEEB6D@apple.com>
References: <4AA26CD9.10007@gmail.com>
<6a8523d60909061449u5ce9b254t9a6398e5e313f4ee@mail.gmail.com>
<70A73AA7-DF18-44A6-B773-AC05DDDEEB6D@apple.com>
Message-ID: <4AA56617.7000108@gmail.com>
On 2009-09-07 21:46, Shantonu Sen wrote:
> This patch looks scary to me. Do we really want to invest in moving to
> a new autoconf/libtool/automake version that I'm told has known
> incompatibilities (which means it's unlikely to be used by anyone else)?
I can't regenerate llvm's configure with autoconf 2.61 or autoconf 2.64
which are the only ones available on Debian.
The regeneration succeeds, but there is a syntax error in configure when
run (a libtool macro is not expanded).
I'd like to support both autoconf 2.60 and 2.64.
Thanks for the review, comments below and new patch attached.
>
> Some specific issues:
> 1)
>> dnl Indicate that we require autoconf 2.59 or later. Ths is needed
>> because we
>> dnl use some autoconf macros only available in 2.59.
>> -AC_PREREQ(2.59)
>> +AC_PREREQ(2.64)
>
> Please update the comments
Sorry that should be AC_PREREQ(2.60), it should still work with autoconf
2.60.
I changed AutoRegen.sh to accept both. If you have autoconf 2.60 can you
try whether ./AutoRegen.sh works for you with my patch applied?
>
> 2)
>> -want_libtool_version='1\.5\.22'
>
> What version of libtool is being used? I can't figure it out. Where is
> it documented?
In the newly attached I kept libtool at what LLVM currently has, only
one macro is used from it though, see below: AC_PROG_NM.
As such I don't think libtool needs to be upgraded.
>
> 3)
>> 3. Copy /ltdl.m4 to llvm/autoconf/m4
>> + 3. Copy /ltsugar.m4 to llvm/autoconf/m4
>> 4. Copy /share/aclocal/libtool.m4 to llvm/autoconf/m4/libtool.m4
>
> You didn't update any of the step numbering, leading to many duplicate
> numbered steps and gaps of steps.
Dropped this section from README now, libtool doesn't need to be updated
since we don't use libtool per se.
>
> 4) I thought the policy was not to upgrade config.guess? Even if not,
> you've lost several local LLVM changes:
>> *:Darwin:*:*)
>> UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
>> case $UNAME_PROCESSOR in
>> - *86) UNAME_PROCESSOR=i686 ;;
>> unknown) UNAME_PROCESSOR=powerpc ;;
>> esac
>
> I don't know what else was overwritten, but it can't be good.
Didn't know it had LLVM local changes, I'll remove the config.* updates
from my patch, and keep them as is.
>
> 6) These changes use libtool internal macros, like
> "_LT_PROG_ECHO_BACKSLASH". These are not stable, and should not be
> used by configure scripts.
>
> I think this requirements more refinement.
Yeah that is hackish, I've done it like that to cut down configure size.
However libtool is currently only used to detect the extension of shared
libraries, and for AC_PROG_NM.
Detecting the shared lib extension with libtool needs LT_INIT that adds
another 300K bloat to configure, instead my latest patch determines
the shared lib extension with a much simpler m4 macro I copied from
LLVM's libtool.m4.
I think the libtool.m4 in LLVM allows that, it only has this copyright:
## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
## Free Software Foundation, Inc.
## Originally by Gordon Matzigkeit , 1996
##
## This file is free software; the Free Software Foundation gives
## unlimited permission to copy and/or distribute it, with or without
## modifications, as long as this notice is preserved.
full.patch.gz:
autoconf/depcomp | 522
autoconf/ltmain.sh | 6863 -------
autoconf/m4/bison.m4 | 15
autoconf/m4/cxx_bidi_iterator.m4 | 22
autoconf/m4/cxx_fwd_iterator.m4 | 22
autoconf/m4/cxx_namespaces.m4 | 19
autoconf/m4/cxx_std_iterator.m4 | 26
autoconf/m4/flex.m4 | 17
autoconf/m4/ltdl.m4 | 418
autoconf/missing | 353
b/autoconf/AutoRegen.sh | 10
b/autoconf/README.TXT | 35
b/autoconf/configure.ac | 40
b/autoconf/install-sh | 530
b/autoconf/m4/path_tclsh.m4 | 4
b/autoconf/m4/shrext.m4 | 38
b/autoconf/mkinstalldirs | 40
b/configure |32893
++++----------------------------------
b/include/llvm/Config/config.h.in | 168
19 files changed, 4522 insertions(+), 37513 deletions(-)
Best regards,
--Edwin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Update-configure.ac-to-work-with-autoconf-2.64.patch
Type: text/x-diff
Size: 8556 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090907/28b6fcf3/attachment.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Update-install-sh-and-mkinstalldirs.patch
Type: text/x-diff
Size: 21038 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090907/28b6fcf3/attachment-0001.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Remove-obsolete-m4-macros-and-unused-programs.-Also-.patch.gz
Type: application/x-gzip
Size: 115054 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090907/28b6fcf3/attachment.gz
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0004-Regenerate-configure-and-config.h.in.patch.gz
Type: application/x-gzip
Size: 200136 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090907/28b6fcf3/attachment-0001.gz
-------------- next part --------------
A non-text attachment was scrubbed...
Name: full.patch.gz
Type: application/x-gzip
Size: 270217 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090907/28b6fcf3/attachment-0002.gz
From nicholas at mxc.ca Mon Sep 7 15:44:51 2009
From: nicholas at mxc.ca (Nick Lewycky)
Date: Mon, 07 Sep 2009 20:44:51 -0000
Subject: [llvm-commits] [llvm] r81156 - /llvm/trunk/lib/VMCore/Verifier.cpp
Message-ID: <200909072044.n87KipRI029141@zion.cs.uiuc.edu>
Author: nicholas
Date: Mon Sep 7 15:44:51 2009
New Revision: 81156
URL: http://llvm.org/viewvc/llvm-project?rev=81156&view=rev
Log:
Homogenize whitespace.
Modified:
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=81156&r1=81155&r2=81156&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Sep 7 15:44:51 2009
@@ -114,7 +114,7 @@
// What to do if verification fails.
Module *Mod; // Module we are verifying right now
DominatorTree *DT; // Dominator Tree, caution can be null!
-
+
std::string Messages;
raw_string_ostream MessagesStr;
@@ -233,9 +233,9 @@
void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB);
using InstVisitor::visit;
-
+
void visit(Instruction &I);
-
+
void visitTruncInst(TruncInst &I);
void visitZExtInst(ZExtInst &I);
void visitSExtInst(SExtInst &I);
@@ -385,7 +385,7 @@
Assert1(!GV.isConstant(), "'common' global may not be marked constant!",
&GV);
}
-
+
// Verify that any metadata used in a global initializer points only to
// other globals.
if (MDNode *FirstNode = dyn_cast(GV.getInitializer())) {
@@ -535,16 +535,17 @@
static bool VerifyAttributeCount(const AttrListPtr &Attrs, unsigned Params) {
if (Attrs.isEmpty())
return true;
-
+
unsigned LastSlot = Attrs.getNumSlots() - 1;
unsigned LastIndex = Attrs.getSlot(LastSlot).Index;
if (LastIndex <= Params
|| (LastIndex == (unsigned)~0
&& (LastSlot == 0 || Attrs.getSlot(LastSlot - 1).Index <= Params)))
return true;
-
+
return false;
}
+
// visitFunction - Verify that a function is ok.
//
void Verifier::visitFunction(Function &F) {
@@ -586,7 +587,7 @@
"Varargs functions must have C calling conventions!", &F);
break;
}
-
+
bool isLLVMdotName = F.getName().size() >= 5 &&
F.getName().substr(0, 5) == "llvm.";
if (!isLLVMdotName)
@@ -623,7 +624,6 @@
}
}
-
// verifyBasicBlock - Verify that a basic block is well formed...
//
void Verifier::visitBasicBlock(BasicBlock &BB) {
@@ -640,7 +640,6 @@
std::sort(Preds.begin(), Preds.end());
PHINode *PN;
for (BasicBlock::iterator I = BB.begin(); (PN = dyn_cast(I));++I) {
-
// Ensure that PHI nodes have at least one entry!
Assert1(PN->getNumIncomingValues() != 0,
"PHI nodes must have at least one entry. If the block is dead, "
@@ -716,7 +715,7 @@
CheckFailed("Function return type does not match operand "
"type of return inst!", &RI, F->getReturnType());
}
-
+
// Check to make sure that the return value has necessary properties for
// terminators...
visitTerminatorInst(RI);
@@ -743,7 +742,6 @@
visitInstruction(SI);
}
-
/// visitUserOp1 - User defined operators shouldn't live beyond the lifetime of
/// a pass, if any exist, it's an error.
///
@@ -1273,11 +1271,10 @@
Assert1(*UI != (User*)&I || !DT->isReachableFromEntry(BB),
"Only PHI nodes may reference their own value!", &I);
}
-
+
// Verify that if this is a terminator that it is at the end of the block.
if (isa(I))
Assert1(BB->getTerminator() == &I, "Terminator not at end of block!", &I);
-
// Check that void typed values don't have names
Assert1(I.getType() != Type::getVoidTy(I.getContext()) || !I.hasName(),
@@ -1301,7 +1298,6 @@
Assert1(PTy->getElementType() != Type::getMetadataTy(I.getContext()),
"Instructions may not produce pointer to metadata.", &I);
-
// Check that all uses of the instruction, if they are instructions
// themselves, actually have parent basic blocks. If the use is not an
// instruction, it is an error!
@@ -1327,7 +1323,7 @@
dyn_cast(I.getOperand(i)->getType()))
Assert1(PTy->getElementType() != Type::getMetadataTy(I.getContext()),
"Invalid use of metadata pointer.", &I);
-
+
if (Function *F = dyn_cast(I.getOperand(i))) {
// Check to make sure that the "address of" an intrinsic function is never
// taken.
@@ -1430,11 +1426,11 @@
Function *IF = CI.getCalledFunction();
Assert1(IF->isDeclaration(), "Intrinsic functions should never be defined!",
IF);
-
+
#define GET_INTRINSIC_VERIFIER
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_VERIFIER
-
+
switch (ID) {
default:
break;
@@ -1461,7 +1457,7 @@
Assert1(isa(CI.getOperand(2)),
"llvm.gcroot parameter #2 must be a constant.", &CI);
}
-
+
Assert1(CI.getParent()->getParent()->hasGC(),
"Enclosing function does not use GC.", &CI);
break;
@@ -1660,7 +1656,7 @@
va_list VA;
va_start(VA, ParamNum);
const FunctionType *FTy = F->getFunctionType();
-
+
// For overloaded intrinsics, the Suffix of the function name must match the
// types of the arguments. This variable keeps track of the expected
// suffix, to be checked at the end.
@@ -1761,7 +1757,7 @@
Verifier *V = new Verifier(action);
PM.add(V);
PM.run(const_cast(M));
-
+
if (ErrorInfo && V->Broken)
*ErrorInfo = V->MessagesStr.str();
return V->Broken;
From nicholas at mxc.ca Mon Sep 7 16:50:25 2009
From: nicholas at mxc.ca (Nick Lewycky)
Date: Mon, 07 Sep 2009 21:50:25 -0000
Subject: [llvm-commits] [llvm] r81157 - /llvm/trunk/lib/VMCore/Verifier.cpp
Message-ID: <200909072150.n87LoPtL005243@zion.cs.uiuc.edu>
Author: nicholas
Date: Mon Sep 7 16:50:24 2009
New Revision: 81157
URL: http://llvm.org/viewvc/llvm-project?rev=81157&view=rev
Log:
Express this in the canonical way.
Modified:
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=81157&r1=81156&r2=81157&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Sep 7 16:50:24 2009
@@ -866,8 +866,8 @@
const Type *SrcTy = I.getOperand(0)->getType();
const Type *DestTy = I.getType();
- bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID;
- bool DstVec = DestTy->getTypeID() == Type::VectorTyID;
+ bool SrcVec = isa(SrcTy);
+ bool DstVec = isa(DestTy);
Assert1(SrcVec == DstVec,
"SIToFP source and dest must both be vector or scalar", &I);
From clattner at apple.com Mon Sep 7 17:12:08 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 15:12:08 -0700
Subject: [llvm-commits] [PATCH] Add malloc call utility functions
In-Reply-To: <4AA25B50.2020208@free.fr>
References: <1B994CDD-5E0A-4255-8B22-1781A229B2BB@apple.com>
<4AA25B50.2020208@free.fr>
Message-ID: <63F4F220-93E8-4D5B-B21F-A889FF72432E@apple.com>
On Sep 5, 2009, at 5:36 AM, Duncan Sands wrote:
> Hi Victor, when bitcode containing a MallocInst is read, it looks
> like you plan to turn this into a malloc call ignoring the alignment
> value of the MallocInst. However if the alignment was huge, the
> pointer
> returned by the malloc call might not be sufficiently aligned. In
> this
> case you would need to allocate a larger amount of memory and adjust
> the
> returned pointer to be sufficiently aligned. The extra complexity may
> not be worth it: I don't know if anyone ever used huge alignments with
> MallocInst, or even if codegen respected these alignments. If you
> decide to ignore the alignment I suggest you add a comment about this.
The MallocInst alignment field is already ignored by all versions of
llvm. Don't worry about this.
-Chris
From sabre at nondot.org Mon Sep 7 17:14:42 2009
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 07 Sep 2009 22:14:42 -0000
Subject: [llvm-commits] [llvm] r81158 -
/llvm/trunk/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll
Message-ID: <200909072214.n87MEg75008321@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 17:14:41 2009
New Revision: 81158
URL: http://llvm.org/viewvc/llvm-project?rev=81158&view=rev
Log:
tweak test, add PR#
Modified:
llvm/trunk/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll
Modified: llvm/trunk/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll?rev=81158&r1=81157&r2=81158&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll (original)
+++ llvm/trunk/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll Mon Sep 7 17:14:41 2009
@@ -1,10 +1,11 @@
; RUN: opt -tailcallelim %s | llvm-dis | FileCheck %s
+; PR615
declare void @bar(i32*)
define i32 @foo() {
; CHECK: i32 @foo()
-; CHECK: alloca
+; CHECK-NEXT: alloca
%A = alloca i32 ; [#uses=2]
store i32 17, i32* %A
call void @bar( i32* %A )
From sabre at nondot.org Mon Sep 7 17:15:23 2009
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 07 Sep 2009 22:15:23 -0000
Subject: [llvm-commits] [llvm] r81159 -
/llvm/trunk/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll
Message-ID: <200909072215.n87MFNps008421@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 17:15:23 2009
New Revision: 81159
URL: http://llvm.org/viewvc/llvm-project?rev=81159&view=rev
Log:
tighten test.
Modified:
llvm/trunk/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll
Modified: llvm/trunk/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll?rev=81159&r1=81158&r2=81159&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll (original)
+++ llvm/trunk/test/Transforms/LoopStrengthReduce/exit_compare_live_range.ll Mon Sep 7 17:15:23 2009
@@ -12,7 +12,7 @@
volatile store float 0.000000e+00, float* %D
%indvar.next = add i32 %indvar, 1 ; [#uses=2]
; CHECK: icmp
-; CHECK: br i1
+; CHECK-NEXT: br i1
%exitcond = icmp eq i32 %indvar.next, %E ; [#uses=1]
br i1 %exitcond, label %loopexit, label %no_exit
loopexit: ; preds = %no_exit
From clattner at apple.com Mon Sep 7 17:15:44 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 15:15:44 -0700
Subject: [llvm-commits] [llvm] r81083 - in /llvm/trunk/test:
CodeGen/X86/ Transforms/ConstantMerge/ Transforms/GVN/
Transforms/IndVarSimplify/ Transforms/Inline/
Transforms/InstCombine/ Transforms/LoopStrengthReduce/
Transforms/SimplifyLibCalls/ Transforms/TailCallElim/
In-Reply-To: <200909051135.n85BZIaM031538@zion.cs.uiuc.edu>
References: <200909051135.n85BZIaM031538@zion.cs.uiuc.edu>
Message-ID:
On Sep 5, 2009, at 4:35 AM, Daniel Dunbar wrote:
> Author: ddunbar
> Date: Sat Sep 5 06:35:16 2009
> New Revision: 81083
>
> URL: http://llvm.org/viewvc/llvm-project?rev=81083&view=rev
> Log:
> Eliminate uses of %prcontext.
> - I'd appreciate it if someone else eyeballs my changes to make sure
> I captured
> the intent of the test.
Great, thanks Daniel!
-Chris
From clattner at apple.com Mon Sep 7 17:17:00 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 15:17:00 -0700
Subject: [llvm-commits] [llvm] r81045 - in /llvm/trunk:
lib/VMCore/LLVMContext.cpp lib/VMCore/Metadata.cpp
test/Transforms/GlobalDCE/2009-09-03-MDNode.ll
In-Reply-To: <200909042132.n84LW7eZ007146@zion.cs.uiuc.edu>
References: <200909042132.n84LW7eZ007146@zion.cs.uiuc.edu>
Message-ID:
On Sep 4, 2009, at 2:32 PM, Devang Patel wrote:
> Author: dpatel
> Date: Fri Sep 4 16:32:05 2009
> New Revision: 81045
>
> URL: http://llvm.org/viewvc/llvm-project?rev=81045&view=rev
> Log:
> While replacing an MDNode elment, properly update MDNode's operand
> list.
> MDNode's operand list does not include all elements.
Devang, please minimize this testcase by hand. You should be able to
reproduce this problem with a 10-15 line .ll file.
-Chris
>
> Added:
> llvm/trunk/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll
> Modified:
> llvm/trunk/lib/VMCore/LLVMContext.cpp
> llvm/trunk/lib/VMCore/Metadata.cpp
>
> Modified: llvm/trunk/lib/VMCore/LLVMContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/LLVMContext.cpp?rev=81045&r1=81044&r2=81045&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/VMCore/LLVMContext.cpp (original)
> +++ llvm/trunk/lib/VMCore/LLVMContext.cpp Fri Sep 4 16:32:05 2009
> @@ -62,9 +62,10 @@
> return Changed;
>
> while (!DeadMDNodes.empty()) {
> - const MDNode *N = cast(DeadMDNodes.back());
> DeadMDNodes.pop_back();
> - if (N->use_empty())
> - delete N;
> + Value *V = DeadMDNodes.back(); DeadMDNodes.pop_back();
> + if (const MDNode *N = dyn_cast_or_null(V))
> + if (N->use_empty())
> + delete N;
> }
> }
> return Changed;
>
> Modified: llvm/trunk/lib/VMCore/Metadata.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Metadata.cpp?rev=81045&r1=81044&r2=81045&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/VMCore/Metadata.cpp (original)
> +++ llvm/trunk/lib/VMCore/Metadata.cpp Fri Sep 4 16:32:05 2009
> @@ -72,6 +72,9 @@
> // Only record metadata uses.
> if (MetadataBase *MB = dyn_cast_or_null(Vals[i]))
> OperandList[NumOperands++] = MB;
> + else if(Vals[i] &&
> + Vals[i]->getType()->getTypeID() == Type::MetadataTyID)
> + OperandList[NumOperands++] = Vals[i];
> Node.push_back(ElementVH(Vals[i], this));
> }
> }
> @@ -144,6 +147,27 @@
> pImpl->MDNodeSet.RemoveNode(this);
> }
>
> + // MDNode only lists metadata elements in operand list, because
> MDNode
> + // used by MDNode is considered a valid use. However on the side,
> MDNode
> + // using a non-metadata value is not considered a "use" of non-
> metadata
> + // value.
> + SmallVector OpIndexes;
> + unsigned OpIndex = 0;
> + for (User::op_iterator OI = op_begin(), OE = op_end();
> + OI != OE; ++OI, OpIndex++) {
> + if (*OI == From)
> + OpIndexes.push_back(OpIndex);
> + }
> + if (MetadataBase *MDTo = dyn_cast_or_null(To)) {
> + for (SmallVector::iterator OI = OpIndexes.begin(),
> + OE = OpIndexes.end(); OI != OE; ++OI)
> + setOperand(*OI, MDTo);
> + } else {
> + for (SmallVector::iterator OI = OpIndexes.begin(),
> + OE = OpIndexes.end(); OI != OE; ++OI)
> + setOperand(*OI, 0);
> + }
> +
> // Replace From element(s) in place.
> for (SmallVector::iterator I = Indexes.begin(), E =
> Indexes.end();
> I != E; ++I) {
>
> Added: llvm/trunk/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll?rev=81045&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll (added)
> +++ llvm/trunk/test/Transforms/GlobalDCE/2009-09-03-MDNode.ll Fri
> Sep 4 16:32:05 2009
> @@ -0,0 +1,264 @@
> +; RUN: llvm-as < %s | opt -globaldce | llc -O0 -o /dev/null
> +
> +%struct..0__pthread_mutex_s = type { i32, i32, i32, i32, i32, i32,
> %struct.__pthread_list_t }
> +%"struct.__gnu_cxx::_ConvertibleConcept"
> = type { i32 }
> +%struct.__pthread_list_t = type { %struct.__pthread_list_t*,
> %struct.__pthread_list_t* }
> +%struct.pthread_attr_t = type { i64, [48 x i8] }
> +%struct.pthread_mutex_t = type { %struct..0__pthread_mutex_s }
> +
> + at _ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)
> * @pthread_once ; [#uses=0]
> + at _ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)*
> @pthread_getspecific ; [#uses=0]
> + at _ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)*
> @pthread_setspecific ; [#uses=0]
> + at _ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias
> weak i32 (i64*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)*
> @pthread_create ; i8*)*> [#uses=0]
> + at _ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)*
> @pthread_cancel ; [#uses=0]
> + at _ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32
> (%struct.pthread_mutex_t*)* @pthread_mutex_lock ; (%struct.pthread_mutex_t*)*> [#uses=0]
> + at _ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak
> i32 (%struct.pthread_mutex_t*)* @pthread_mutex_trylock ; (%struct.pthread_mutex_t*)*> [#uses=0]
> + at _ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak
> i32 (%struct.pthread_mutex_t*)* @pthread_mutex_unlock ; (%struct.pthread_mutex_t*)*> [#uses=0]
> +
> @_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t
> = alias weak i32 (%struct.pthread_mutex_t*,
> %"struct.__gnu_cxx::_ConvertibleConcept"*)
> * @pthread_mutex_init ; %"struct.__gnu_cxx::_ConvertibleConcept"*)
> *> [#uses=0]
> + at _ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*,
> void (i8*)*)* @pthread_key_create ;
> [#uses=0]
> + at _ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)*
> @pthread_key_delete ; [#uses=0]
> + at _ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias
> weak i32 (%"struct.__gnu_cxx::_ConvertibleConcept int,unsigned int>"*)* @pthread_mutexattr_init ; (%"struct.__gnu_cxx::_ConvertibleConcept int>"*)*> [#uses=0]
> + at _ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti =
> alias weak i32 (%"struct.__gnu_cxx::_ConvertibleConcept int,unsigned int>"*, i32)* @pthread_mutexattr_settype ; (%"struct.__gnu_cxx::_ConvertibleConcept int>"*, i32)*> [#uses=0]
> + at _ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t =
> alias weak i32 (%"struct.__gnu_cxx::_ConvertibleConcept int,unsigned int>"*)* @pthread_mutexattr_destroy ; (%"struct.__gnu_cxx::_ConvertibleConcept int>"*)*> [#uses=0]
> +
> +define weak void @_ZN9__gnu_cxx26__aux_require_boolean_exprIbEEvRKT_
> (i8* %__t) {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !0)
> + tail call void @llvm.dbg.stoppoint(i32 240, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !0)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_19_ConvertibleConceptIjjEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !8)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !8)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPcEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !11)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !11)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKcEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !12)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !12)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPwEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !13)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !13)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKwEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !14)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !14)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPwEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !15)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !15)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPcEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !16)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !16)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIiEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !17)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !17)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIlEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !18)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !18)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIxEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !19)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !19)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIjEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !20)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !20)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIcSt11char_traitsIcEEcEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !21)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !21)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIwSt11char_traitsIwEEwEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !22)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !22)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPcEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !23)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !23)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKcEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !24)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !24)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKcSsEEEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !25)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !25)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPcSsEEEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !26)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !26)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKwSbIwSt11char_traitsIwESaIwEEEEEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !27)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !27)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPwSbIwSt11char_traitsIwESaIwEEEEEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !28)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !28)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPwEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !29)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !29)
> + ret void
> +}
> +
> +define weak void
> @_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKwEEEEvv
> () {
> +entry:
> + tail call void @llvm.dbg.func.start(metadata !30)
> + tail call void @llvm.dbg.stoppoint(i32 63, i32 0, metadata !2)
> + tail call void @llvm.dbg.region.end(metadata !30)
> + ret void
> +}
> +
> +declare void @llvm.dbg.func.start(metadata) nounwind readnone
> +
> +declare void @llvm.dbg.stoppoint(i32, i32, metadata) nounwind
> readnone
> +
> +declare void @llvm.dbg.region.end(metadata) nounwind readnone
> +
> +declare extern_weak i32 @pthread_once(i32*, void ()*)
> +
> +declare extern_weak i8* @pthread_getspecific(i32)
> +
> +declare extern_weak i32 @pthread_setspecific(i32, i8*)
> +
> +declare extern_weak i32 @pthread_create(i64*,
> %struct.pthread_attr_t*, i8* (i8*)*, i8*)
> +
> +declare extern_weak i32 @pthread_cancel(i64)
> +
> +declare extern_weak i32 @pthread_mutex_lock(%struct.pthread_mutex_t*)
> +
> +declare extern_weak i32 @pthread_mutex_trylock
> (%struct.pthread_mutex_t*)
> +
> +declare extern_weak i32 @pthread_mutex_unlock
> (%struct.pthread_mutex_t*)
> +
> +declare extern_weak i32 @pthread_mutex_init
> (%struct.pthread_mutex_t*,
> %"struct.__gnu_cxx::_ConvertibleConcept"*)
> +
> +declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*)
> +
> +declare extern_weak i32 @pthread_key_delete(i32)
> +
> +declare extern_weak i32 @pthread_mutexattr_init
> (%"struct.__gnu_cxx::_ConvertibleConcept"*)
> +
> +declare extern_weak i32 @pthread_mutexattr_settype
> (%"struct.__gnu_cxx::_ConvertibleConcept int>"*, i32)
> +
> +declare extern_weak i32 @pthread_mutexattr_destroy
> (%"struct.__gnu_cxx::_ConvertibleConcept"*)
> +
> +!0 = metadata !{i32 458798, i32 0, metadata !1,
> metadata !"__aux_require_boolean_expr",
> metadata !"__aux_require_boolean_expr",
> metadata !"_ZN9__gnu_cxx26__aux_require_boolean_exprIbEEvRKT_",
> metadata !2, i32 239, metadata !3, i1 false, i1 true}
> +!1 = metadata !{i32 458769, i32 0, i32 4, metadata !"concept-
> inst.cc", metadata !"/home/buildbot/buildslave/llvm-x86_64-linux-
> selfhost/llvm-gcc.obj/x86_64-unknown-linux-gnu/libstdc++-v3/
> src/../../../../llvm-gcc.src/libstdc++-v3/src", metadata !"4.2.1
> (Based on Apple Inc. build 5649) (LLVM build)", i1 true, i1 true,
> metadata !"", i32 0}
> +!2 = metadata !{i32 458769, i32 0, i32 4,
> metadata !"boost_concept_check.h", metadata !"/home/buildbot/
> buildslave/llvm-x86_64-linux-selfhost/llvm-gcc.obj/x86_64-unknown-
> linux-gnu/libstdc++-v3/include/bits", metadata !"4.2.1 (Based on
> Apple Inc. build 5649) (LLVM build)", i1 false, i1 true,
> metadata !"", i32 0}
> +!3 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1,
> i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0}
> +!4 = metadata !{null, metadata !5}
> +!5 = metadata !{i32 458768, metadata !1, metadata !"", metadata !1,
> i32 0, i64 64, i64 64, i64 0, i32 0, metadata !6}
> +!6 = metadata !{i32 458790, metadata !1, metadata !"", metadata !1,
> i32 0, i64 8, i64 8, i64 0, i32 0, metadata !7}
> +!7 = metadata !{i32 458788, metadata !1, metadata !"bool",
> metadata !1, i32 0, i64 8, i64 8, i64 0, i32 0, i32 2}
> +!8 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_ConvertibleConcept unsigned int> >",
> metadata
> !"__function_requires<__gnu_cxx::_ConvertibleConcept unsigned int> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_19_ConvertibleConceptIjjEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!9 = metadata !{i32 458773, metadata !1, metadata !"", metadata !1,
> i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !10, i32 0}
> +!10 = metadata !{null}
> +!11 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept >",
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPcEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!12 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept
> >",
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept
> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKcEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!13 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept
> >",
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept
> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPwEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!14 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept wchar_t*> >",
> metadata
> !"__function_requires<__gnu_cxx::_InputIteratorConcept wchar_t*> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_21_InputIteratorConceptIPKwEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!15 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <__gnu_cxx::_LessThanComparableConcept >",
> metadata
> !"__function_requires
> <__gnu_cxx::_LessThanComparableConcept >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPwEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!16 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept
> >",
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept
> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIPcEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!17 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept
> >",
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept
> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIiEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!18 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept int> >",
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept int> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIlEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!19 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept long int> >",
> metadata
> !"__function_requires<__gnu_cxx::_LessThanComparableConcept long int> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIxEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!20 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <__gnu_cxx::_LessThanComparableConcept >",
> metadata
> !"__function_requires
> <__gnu_cxx::_LessThanComparableConcept >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_26_LessThanComparableConceptIjEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!21 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <__gnu_cxx::_OutputIteratorConcept std::char_traits >, char> >",
> metadata
> !"__function_requires
> <__gnu_cxx::_OutputIteratorConcept std::char_traits >, char> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIcSt11char_traitsIcEEcEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!22 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <__gnu_cxx::_OutputIteratorConcept std::char_traits >, wchar_t> >",
> metadata
> !"__function_requires
> <__gnu_cxx::_OutputIteratorConcept std::char_traits >, wchar_t> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_22_OutputIteratorConceptISt19ostreambuf_iteratorIwSt11char_traitsIwEEwEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!23 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <__gnu_cxx::_RandomAccessIteratorConcept >",
> metadata
> !"__function_requires
> <__gnu_cxx::_RandomAccessIteratorConcept >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPcEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!24 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept char*> >",
> metadata
> !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept char*> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKcEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!25 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator char*, std::basic_string,
> std::allocator > > > >",
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator char*, std::basic_string,
> std::allocator > > > >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKcSsEEEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!26 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator std::basic_string, std::allocator
> > > > >",
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator std::basic_string, std::allocator
> > > > >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPcSsEEEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!27 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator wchar_t*, std::basic_string,
> std::allocator > > > >",
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept<__gnu_cxx::__normal_iterator wchar_t*, std::basic_string,
> std::allocator > > > >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPKwSbIwSt11char_traitsIwESaIwEEEEEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!28 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept
> <__gnu_cxx::__normal_iterator std::char_traits, std::allocator > > > >",
> metadata
> !"__function_requires
> <
> __gnu_cxx
> ::_RandomAccessIteratorConcept
> <__gnu_cxx::__normal_iterator std::char_traits, std::allocator > > > >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptINS_17__normal_iteratorIPwSbIwSt11char_traitsIwESaIwEEEEEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!29 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires
> <__gnu_cxx::_RandomAccessIteratorConcept >",
> metadata
> !"__function_requires
> <__gnu_cxx::_RandomAccessIteratorConcept >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPwEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
> +!30 = metadata !{i32 458798, i32 0, metadata !1,
> metadata
> !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept wchar_t*> >",
> metadata
> !"__function_requires<__gnu_cxx::_RandomAccessIteratorConcept wchar_t*> >",
> metadata
> !"_ZN9__gnu_cxx19__function_requiresINS_28_RandomAccessIteratorConceptIPKwEEEEvv
> ", metadata !2, i32 61, metadata !9, i1 false, i1 true}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From clattner at apple.com Mon Sep 7 17:23:27 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 15:23:27 -0700
Subject: [llvm-commits] [llvm] r80963 - in /llvm/trunk:
include/llvm/CodeGen/FastISel.h
lib/CodeGen/SelectionDAG/FastISel.cpp
test/CodeGen/X86/fast-isel-fneg.ll
In-Reply-To: <200909032253.n83Mrvlj011046@zion.cs.uiuc.edu>
References: <200909032253.n83Mrvlj011046@zion.cs.uiuc.edu>
Message-ID:
On Sep 3, 2009, at 3:53 PM, Dan Gohman wrote:
> Author: djg
> Date: Thu Sep 3 17:53:57 2009
> New Revision: 80963
>
> URL: http://llvm.org/viewvc/llvm-project?rev=80963&view=rev
> Log:
> LLVM currently represents floating-point negation as -0.0 - x. Fix
> FastISel to recognize this pattern and emit a floating-point
> negation using xor.
ISD::XOR is legal for floating point operands?
-Chris
>
> Added:
> llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll
> Modified:
> llvm/trunk/include/llvm/CodeGen/FastISel.h
> llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=80963&r1=80962&r2=80963&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/FastISel.h Thu Sep 3 17:53:57
> 2009
> @@ -300,6 +300,8 @@
> private:
> bool SelectBinaryOp(User *I, ISD::NodeType ISDOpcode);
>
> + bool SelectFNeg(User *I);
> +
> bool SelectGetElementPtr(User *I);
>
> bool SelectCall(User *I);
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=80963&r1=80962&r2=80963&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Sep 3
> 17:53:57 2009
> @@ -608,6 +608,26 @@
> MBB->addSuccessor(MSucc);
> }
>
> +/// SelectFNeg - Emit an FNeg operation.
> +///
> +bool
> +FastISel::SelectFNeg(User *I) {
> + unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument
> (I));
> + if (OpReg == 0) return false;
> +
> + // Twiddle the sign bit with xor.
> + EVT VT = TLI.getValueType(I->getType());
> + if (VT.getSizeInBits() > 64) return false;
> + unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISD::XOR,
> OpReg,
> + UINT64_C(1) << (VT.getSizeInBits
> ()-1),
> + VT.getSimpleVT());
> + if (ResultReg == 0)
> + return false;
> +
> + UpdateValueMap(I, ResultReg);
> + return true;
> +}
> +
> bool
> FastISel::SelectOperator(User *I, unsigned Opcode) {
> switch (Opcode) {
> @@ -618,6 +638,9 @@
> case Instruction::Sub:
> return SelectBinaryOp(I, ISD::SUB);
> case Instruction::FSub:
> + // FNeg is currently represented in LLVM IR as a special case
> of FSub.
> + if (BinaryOperator::isFNeg(I))
> + return SelectFNeg(I);
> return SelectBinaryOp(I, ISD::FSUB);
> case Instruction::Mul:
> return SelectBinaryOp(I, ISD::MUL);
>
> Added: llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll?rev=80963&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll Thu Sep 3
> 17:53:57 2009
> @@ -0,0 +1,15 @@
> +; RUN: llvm-as < %s | llc -fast-isel -march=x86-64 | FileCheck %s
> +
> +; CHECK: doo:
> +; CHECK: xorpd
> +define double @doo(double %x) nounwind {
> + %y = fsub double -0.0, %x
> + ret double %y
> +}
> +
> +; CHECK: foo:
> +; CHECK: xorps
> +define float @foo(float %x) nounwind {
> + %y = fsub float -0.0, %x
> + ret float %y
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From clattner at apple.com Mon Sep 7 17:24:24 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 15:24:24 -0700
Subject: [llvm-commits] [llvm] r80962 -
/llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp
In-Reply-To: <200909032248.n83MmqYN010342@zion.cs.uiuc.edu>
References: <200909032248.n83MmqYN010342@zion.cs.uiuc.edu>
Message-ID:
On Sep 3, 2009, at 3:48 PM, David Goodwin wrote:
> Author: david_goodwin
> Date: Thu Sep 3 17:48:51 2009
> New Revision: 80962
>
> URL: http://llvm.org/viewvc/llvm-project?rev=80962&view=rev
> Log:
> Don't crash when target has no itineraries.
Hi David,
How about using "if (ItinData.isEmpty()) return;" to reduce nesting?
-Chris
>
> Modified:
> llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp
>
> Modified: llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp?rev=80962&r1=80961&r2=80962&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp (original)
> +++ llvm/trunk/lib/CodeGen/ExactHazardRecognizer.cpp Thu Sep 3
> 17:48:51 2009
> @@ -83,71 +83,75 @@
> }
>
> ExactHazardRecognizer::HazardType
> ExactHazardRecognizer::getHazardType(SUnit *SU) {
> - unsigned cycle = 0;
> + if (!ItinData.isEmpty()) {
> + unsigned cycle = 0;
>
> - // Use the itinerary for the underlying instruction to check for
> - // free FU's in the scoreboard at the appropriate future cycles.
> - unsigned idx = SU->getInstr()->getDesc().getSchedClass();
> - for (const InstrStage *IS = ItinData.beginStage(idx),
> - *E = ItinData.endStage(idx); IS != E; ++IS) {
> - // We must find one of the stage's units free for every cycle the
> - // stage is occupied. FIXME it would be more accurate to find the
> - // same unit free in all the cycles.
> - for (unsigned int i = 0; i < IS->getCycles(); ++i) {
> - assert(((cycle + i) < ScoreboardDepth) &&
> - "Scoreboard depth exceeded!");
> -
> - unsigned index = getFutureIndex(cycle + i);
> - unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
> - if (!freeUnits) {
> - DEBUG(errs() << "*** Hazard in cycle " << (cycle + i) << ",
> ");
> - DEBUG(errs() << "SU(" << SU->NodeNum << "): ");
> - DEBUG(SU->getInstr()->dump());
> - return Hazard;
> + // Use the itinerary for the underlying instruction to check for
> + // free FU's in the scoreboard at the appropriate future cycles.
> + unsigned idx = SU->getInstr()->getDesc().getSchedClass();
> + for (const InstrStage *IS = ItinData.beginStage(idx),
> + *E = ItinData.endStage(idx); IS != E; ++IS) {
> + // We must find one of the stage's units free for every cycle
> the
> + // stage is occupied. FIXME it would be more accurate to find
> the
> + // same unit free in all the cycles.
> + for (unsigned int i = 0; i < IS->getCycles(); ++i) {
> + assert(((cycle + i) < ScoreboardDepth) &&
> + "Scoreboard depth exceeded!");
> +
> + unsigned index = getFutureIndex(cycle + i);
> + unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
> + if (!freeUnits) {
> + DEBUG(errs() << "*** Hazard in cycle " << (cycle + i) <<
> ", ");
> + DEBUG(errs() << "SU(" << SU->NodeNum << "): ");
> + DEBUG(SU->getInstr()->dump());
> + return Hazard;
> + }
> }
> +
> + // Advance the cycle to the next stage.
> + cycle += IS->getNextCycles();
> }
> -
> - // Advance the cycle to the next stage.
> - cycle += IS->getNextCycles();
> }
>
> return NoHazard;
> }
>
> void ExactHazardRecognizer::EmitInstruction(SUnit *SU) {
> - unsigned cycle = 0;
> -
> - // Use the itinerary for the underlying instruction to reserve FU's
> - // in the scoreboard at the appropriate future cycles.
> - unsigned idx = SU->getInstr()->getDesc().getSchedClass();
> - for (const InstrStage *IS = ItinData.beginStage(idx),
> - *E = ItinData.endStage(idx); IS != E; ++IS) {
> - // We must reserve one of the stage's units for every cycle the
> - // stage is occupied. FIXME it would be more accurate to reserve
> - // the same unit free in all the cycles.
> - for (unsigned int i = 0; i < IS->getCycles(); ++i) {
> - assert(((cycle + i) < ScoreboardDepth) &&
> - "Scoreboard depth exceeded!");
> + if (!ItinData.isEmpty()) {
> + unsigned cycle = 0;
>
> - unsigned index = getFutureIndex(cycle + i);
> - unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
> -
> - // reduce to a single unit
> - unsigned freeUnit = 0;
> - do {
> - freeUnit = freeUnits;
> - freeUnits = freeUnit & (freeUnit - 1);
> - } while (freeUnits);
> + // Use the itinerary for the underlying instruction to reserve
> FU's
> + // in the scoreboard at the appropriate future cycles.
> + unsigned idx = SU->getInstr()->getDesc().getSchedClass();
> + for (const InstrStage *IS = ItinData.beginStage(idx),
> + *E = ItinData.endStage(idx); IS != E; ++IS) {
> + // We must reserve one of the stage's units for every cycle the
> + // stage is occupied. FIXME it would be more accurate to
> reserve
> + // the same unit free in all the cycles.
> + for (unsigned int i = 0; i < IS->getCycles(); ++i) {
> + assert(((cycle + i) < ScoreboardDepth) &&
> + "Scoreboard depth exceeded!");
> +
> + unsigned index = getFutureIndex(cycle + i);
> + unsigned freeUnits = IS->getUnits() & ~Scoreboard[index];
> +
> + // reduce to a single unit
> + unsigned freeUnit = 0;
> + do {
> + freeUnit = freeUnits;
> + freeUnits = freeUnit & (freeUnit - 1);
> + } while (freeUnits);
> +
> + assert(freeUnit && "No function unit available!");
> + Scoreboard[index] |= freeUnit;
> + }
>
> - assert(freeUnit && "No function unit available!");
> - Scoreboard[index] |= freeUnit;
> + // Advance the cycle to the next stage.
> + cycle += IS->getNextCycles();
> }
>
> - // Advance the cycle to the next stage.
> - cycle += IS->getNextCycles();
> + DEBUG(dumpScoreboard());
> }
> -
> - DEBUG(dumpScoreboard());
> }
>
> void ExactHazardRecognizer::AdvanceCycle() {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From gohman at apple.com Mon Sep 7 17:31:26 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 22:31:26 -0000
Subject: [llvm-commits] [llvm] r81161 -
/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Message-ID: <200909072231.n87MVQYt010463@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 17:31:26 2009
New Revision: 81161
URL: http://llvm.org/viewvc/llvm-project?rev=81161&view=rev
Log:
Simplify this code by using hasDefinitiveInitializer().
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=81161&r1=81160&r2=81161&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 7 17:31:26 2009
@@ -2024,20 +2024,21 @@
/// we punt. We basically just support direct accesses to globals and GEP's of
/// globals. This should be kept up to date with CommitValueTo.
static bool isSimpleEnoughPointerToCommit(Constant *C, LLVMContext &Context) {
- if (GlobalVariable *GV = dyn_cast(C)) {
- if (!GV->hasExternalLinkage() && !GV->hasLocalLinkage())
- return false; // do not allow weak/linkonce/dllimport/dllexport linkage.
- return !GV->isDeclaration(); // reject external globals.
- }
+ if (GlobalVariable *GV = dyn_cast(C))
+ // Do not allow weak/linkonce/dllimport/dllexport linkage or
+ // external globals.
+ return GV->hasDefinitiveInitializer();
+
if (ConstantExpr *CE = dyn_cast(C))
// Handle a constantexpr gep.
if (CE->getOpcode() == Instruction::GetElementPtr &&
isa(CE->getOperand(0))) {
GlobalVariable *GV = cast(CE->getOperand(0));
- if (!GV->hasExternalLinkage() && !GV->hasLocalLinkage())
- return false; // do not allow weak/linkonce/dllimport/dllexport linkage.
- return GV->hasInitializer() &&
- ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE,
+ // Do not allow weak/linkonce/dllimport/dllexport linkage or
+ // external globals.
+ if (!GV->hasDefinitiveInitializer())
+ return false;
+ return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE,
Context);
}
return false;
From gohman at apple.com Mon Sep 7 17:34:44 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 22:34:44 -0000
Subject: [llvm-commits] [llvm] r81162 -
/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Message-ID: <200909072234.n87MYixH010880@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 17:34:43 2009
New Revision: 81162
URL: http://llvm.org/viewvc/llvm-project?rev=81162&view=rev
Log:
Preserve the InBounds flag when evaluating a getelementptr instruction
into a getelementptr ConstantExpr.
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=81162&r1=81161&r2=81162&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 7 17:34:43 2009
@@ -2227,8 +2227,9 @@
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end();
i != e; ++i)
GEPOps.push_back(getVal(Values, *i));
- InstResult =
- ConstantExpr::getGetElementPtr(P, &GEPOps[0], GEPOps.size());
+ InstResult = cast(GEP)->isInBounds() ?
+ ConstantExpr::getInBoundsGetElementPtr(P, &GEPOps[0], GEPOps.size()) :
+ ConstantExpr::getGetElementPtr(P, &GEPOps[0], GEPOps.size());
} else if (LoadInst *LI = dyn_cast(CurInst)) {
if (LI->isVolatile()) return false; // no volatile accesses.
InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)),
From gohman at apple.com Mon Sep 7 17:40:13 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 22:40:13 -0000
Subject: [llvm-commits] [llvm] r81163 -
/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Message-ID: <200909072240.n87MeDLm011640@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 17:40:13 2009
New Revision: 81163
URL: http://llvm.org/viewvc/llvm-project?rev=81163&view=rev
Log:
Fix GlobalOpt to avoid committing a store if the address getelementptr
is missing the inbounds flag. This is slightly conservative, but it
avoids problems with two constants pointing to the same address but
getting distinct entries in the Memory DenseMap.
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=81163&r1=81162&r2=81163&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 7 17:40:13 2009
@@ -2032,7 +2032,8 @@
if (ConstantExpr *CE = dyn_cast(C))
// Handle a constantexpr gep.
if (CE->getOpcode() == Instruction::GetElementPtr &&
- isa(CE->getOperand(0))) {
+ isa(CE->getOperand(0)) &&
+ cast(CE)->isInBounds()) {
GlobalVariable *GV = cast(CE->getOperand(0));
// Do not allow weak/linkonce/dllimport/dllexport linkage or
// external globals.
From gohman at apple.com Mon Sep 7 17:42:05 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 22:42:05 -0000
Subject: [llvm-commits] [llvm] r81164 -
/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Message-ID: <200909072242.n87Mg56N011876@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 17:42:05 2009
New Revision: 81164
URL: http://llvm.org/viewvc/llvm-project?rev=81164&view=rev
Log:
Don't commit addresses of aggregate values. This avoids problems with
an aggregate store overlapping a different aggregate store, despite
the stores having distinct addresses.
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=81164&r1=81163&r2=81164&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 7 17:42:05 2009
@@ -2024,6 +2024,11 @@
/// we punt. We basically just support direct accesses to globals and GEP's of
/// globals. This should be kept up to date with CommitValueTo.
static bool isSimpleEnoughPointerToCommit(Constant *C, LLVMContext &Context) {
+ // Conservatively, avoid aggregate types. This is because we don't
+ // want to worry about them partially overlapping other stores.
+ if (!cast(C->getType())->getElementType()->isSingleValueType())
+ return false;
+
if (GlobalVariable *GV = dyn_cast(C))
// Do not allow weak/linkonce/dllimport/dllexport linkage or
// external globals.
From gohman at apple.com Mon Sep 7 17:44:55 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 22:44:55 -0000
Subject: [llvm-commits] [llvm] r81165 -
/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Message-ID: <200909072244.n87MitX1012225@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 17:44:55 2009
New Revision: 81165
URL: http://llvm.org/viewvc/llvm-project?rev=81165&view=rev
Log:
Don't commit stores with addresses that have indices that are not
compile-time constant integers or that are out of bounds for their
corresponding static array types. These can cause aliasing that
GlobalOpt assumes won't happen.
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=81165&r1=81164&r2=81165&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Sep 7 17:44:55 2009
@@ -2044,6 +2044,27 @@
// external globals.
if (!GV->hasDefinitiveInitializer())
return false;
+
+ gep_type_iterator GEPI = gep_type_begin(CE), E = gep_type_end(CE);
+ User::op_iterator OI = next(CE->op_begin());
+
+ // The first index must be zero.
+ ConstantInt *CI = dyn_cast(*OI);
+ if (!CI || !CI->isZero()) return false;
+ ++GEPI;
+ ++OI;
+
+ // The remaining indices must be compile-time known integers within the
+ // bounds of the corresponding static array types.
+ for (; GEPI != E; ++GEPI, ++OI) {
+ CI = dyn_cast(*OI);
+ if (!CI) return false;
+ if (const ArrayType *ATy = dyn_cast(*GEPI))
+ if (CI->getValue().getActiveBits() > 64 ||
+ CI->getZExtValue() >= ATy->getNumElements())
+ return false;
+ }
+
return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE,
Context);
}
From gohman at apple.com Mon Sep 7 17:45:41 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 22:45:41 -0000
Subject: [llvm-commits] [llvm] r81166 - in
/llvm/trunk/test/Transforms/GlobalOpt: ctor-list-opt-dbg.ll
ctor-list-opt.ll
Message-ID: <200909072245.n87MjfOD012329@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 17:45:41 2009
New Revision: 81166
URL: http://llvm.org/viewvc/llvm-project?rev=81166&view=rev
Log:
Add inbounds to these getelementptrs, now that GlobalOpt requires this,
to preserve the meaning of these tests.
Modified:
llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll
llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt.ll
Modified: llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll?rev=81166&r1=81165&r2=81166&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll (original)
+++ llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-dbg.ll Mon Sep 7 17:45:41 2009
@@ -56,9 +56,9 @@
}
define internal void @CTOR5() {
- %X.2p = getelementptr { i32, [2 x i32] }* @X, i32 0, i32 1, i32 0 ; [#uses=2]
+ %X.2p = getelementptr inbounds { i32, [2 x i32] }* @X, i32 0, i32 1, i32 0 ; [#uses=2]
%X.2 = load i32* %X.2p ; [#uses=1]
- %X.1p = getelementptr { i32, [2 x i32] }* @X, i32 0, i32 0 ; [#uses=1]
+ %X.1p = getelementptr inbounds { i32, [2 x i32] }* @X, i32 0, i32 0 ; [#uses=1]
store i32 %X.2, i32* %X.1p
store i32 42, i32* %X.2p
ret void
Modified: llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt.ll?rev=81166&r1=81165&r2=81166&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt.ll (original)
+++ llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt.ll Mon Sep 7 17:45:41 2009
@@ -43,9 +43,9 @@
}
define internal void @CTOR5() {
- %X.2p = getelementptr { i32, [2 x i32] }* @X, i32 0, i32 1, i32 0 ; [#uses=2]
+ %X.2p = getelementptr inbounds { i32, [2 x i32] }* @X, i32 0, i32 1, i32 0 ; [#uses=2]
%X.2 = load i32* %X.2p ; [#uses=1]
- %X.1p = getelementptr { i32, [2 x i32] }* @X, i32 0, i32 0 ; [#uses=1]
+ %X.1p = getelementptr inbounds { i32, [2 x i32] }* @X, i32 0, i32 0 ; [#uses=1]
store i32 %X.2, i32* %X.1p
store i32 42, i32* %X.2p
ret void
From sabre at nondot.org Mon Sep 7 17:52:39 2009
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 07 Sep 2009 22:52:39 -0000
Subject: [llvm-commits] [llvm] r81167 - /llvm/trunk/docs/LangRef.html
Message-ID: <200909072252.n87MqeUV013174@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 17:52:39 2009
New Revision: 81167
URL: http://llvm.org/viewvc/llvm-project?rev=81167&view=rev
Log:
describe undef semantics in some more detail.
Modified:
llvm/trunk/docs/LangRef.html
Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=81167&r1=81166&r2=81167&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Mon Sep 7 17:52:39 2009
@@ -2016,13 +2016,109 @@
-
The string 'undef' is recognized as a type-less constant that has no
- specific value. Undefined values may be of any type and be used anywhere a
- constant is permitted.
+
The string 'undef' can be used anywhere a constant is expected, and
+ indicates that the user of the value may recieve an unspecified bit-pattern.
+ Undefined values may be of any type (other than label or void) and be used
+ anywhere a constant is permitted.
+
+
Undefined values are useful, because it indicates to the compiler that the
+ program is well defined no matter what value is used. This gives the
+ compiler more freedom to optimize. Here are some examples of (potentially
+ surprising) transformations that are valid (in pseudo IR):
-
Undefined values indicate to the compiler that the program is well defined no
- matter what value is used, giving the compiler more freedom to optimize.
+
+
+ %A = add %X, undef
+ %B = sub %X, undef
+ %C = xor %X, undef
+Safe:
+ %A = undef
+ %B = undef
+ %C = undef
+
+
+
+
This is safe because all of the output bits are affected by the undef bits.
+Any output bit can have a zero or one depending on the input bits.
+
+
+
+ %A = or %X, undef
+ %B = and %X, undef
+Safe:
+ %A = -1
+ %B = 0
+Unsafe:
+ %A = undef
+ %B = undef
+
+
+
+
These logical operations have bits that are not always affected by the input.
+For example, if "%X" has a zero bit, then the output of the 'and' operation will
+always be a zero, no matter what the corresponding bit from the undef is. As
+such, it is unsafe to optimizer or assume that the result of the and is undef.
+However, it is safe to assume that all bits of the undef are 0, and optimize the
+and to 0. Likewise, it is safe to assume that all the bits of the undef operand
+to the or could be set, allowing the or to be folded to -1.
+
+
+
+ %A = select undef, %X, %Y
+ %B = select undef, 42, %Y
+ %C = select %X, %Y, undef
+Safe:
+ %A = %X (or %Y)
+ %B = 42 (or %Y)
+ %C = %Y
+Unsafe:
+ %A = undef
+ %B = undef
+ %C = undef
+
+
+
+
This set of examples show that undefined select (and conditional branch)
+conditions can go "either way" but they have to come from one of the two
+operands. In the %A example, if %X and %Y were both known to have a clear low
+bit, then %A would have to have a cleared low bit. However, in the %C example,
+the optimizer is allowed to assume that the undef operand could be the same as
+%Y, allowing the whole select to be eliminated.
+
+
+
+
+ %A = xor undef, undef
+
+ %B = undef
+ %C = xor %B, %B
+
+ %D = undef
+ %E = icmp lt %D, 4
+ %F = icmp gte %D, 4
+
+Safe:
+ %A = undef
+ %B = undef
+ %C = undef
+ %D = undef
+ %E = undef
+ %F = undef
+
+
+
+
This example points out that two undef operands are not necessarily the same.
+This can be surprising to people (and also matches C semantics) where they
+assume that "X^X" is always zero, even if X is undef. This isn't true for a
+number of reasons, but the short answer is that an undef "variable" can
+arbitrarily change its value over its "live range". This is true because the
+"variable" doesn't actually have a live range. Instead, the value is
+logically read from arbitrary registers that happen to be around when needed,
+so the value is not neccesarily consistent over time. In fact, %A and %C need
+to have the same semantics of the core LLVM "replace all uses with" concept
+would not hold.
+
From gohman at apple.com Mon Sep 7 18:04:59 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 23:04:59 -0000
Subject: [llvm-commits] [llvm] r81168 -
/llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
Message-ID: <200909072304.n87N4xHi014865@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 18:04:59 2009
New Revision: 81168
URL: http://llvm.org/viewvc/llvm-project?rev=81168&view=rev
Log:
Add a testcase for the GlobalOpt inbounds fix.
Added:
llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
Added: llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll?rev=81168&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll Mon Sep 7 18:04:59 2009
@@ -0,0 +1,23 @@
+; RUN: llvm-as < %s | opt -globalopt | llvm-dis | FileCheck %s
+
+; Don't get fooled by the inbounds keyword; it doesn't change
+; the computed address.
+
+; CHECK: @H = global i32 2
+; CHECK: @I = global i32 2
+
+ at llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
+ at addr = external global i32
+ at G = internal global [6 x [5 x i32]] zeroinitializer
+ at H = global i32 80
+ at I = global i32 90
+
+define internal void @CTOR() {
+ store i32 1, i32* getelementptr ([6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ store i32 2, i32* getelementptr inbounds ([6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ %t = load i32* getelementptr ([6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ store i32 %t, i32* @H
+ %s = load i32* getelementptr inbounds ([6 x [5 x i32]]* @G, i64 0, i64 0, i64 0)
+ store i32 %s, i32* @I
+ ret void
+}
From sabre at nondot.org Mon Sep 7 18:33:52 2009
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 07 Sep 2009 23:33:52 -0000
Subject: [llvm-commits] [llvm] r81170 - /llvm/trunk/docs/LangRef.html
Message-ID: <200909072333.n87NXqwI018462@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 18:33:52 2009
New Revision: 81170
URL: http://llvm.org/viewvc/llvm-project?rev=81170&view=rev
Log:
add some more notes.
Modified:
llvm/trunk/docs/LangRef.html
Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=81170&r1=81169&r2=81170&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Mon Sep 7 18:33:52 2009
@@ -2118,7 +2118,46 @@
so the value is not neccesarily consistent over time. In fact, %A and %C need
to have the same semantics of the core LLVM "replace all uses with" concept
would not hold.
-
+
+
+
+ %A = fdiv undef, %X
+ %B = fdiv %X, undef
+Safe:
+ %A = undef
+b: unreachable
+
+
+
+These examples show the crucial difference between an undefined
+value and undefined behavior. An undefined value (like undef) is
+allowed to have an arbitrary bit-pattern. This means that the %A operation
+can be constant folded to undef because the undef could be an SNaN, and fdiv is
+not (currently) defined on SNaN's. However, in the second example, we can make
+a more aggressive assumption: because the undef is allowed to be an arbitrary
+value, we are allowed to assume that it could be zero. Since a divide by zero
+is has undefined behavior, we are allowed to assume that the operation
+does not execute at all. This allows us to delete the divide and all code after
+it: since the undefined operation "can't happen", the optimizer can assume that
+it occurs in dead code.
+
+
+
+
+a: store undef -> %X
+b: store %X -> undef
+Safe:
+a: <deleted>
+b: unreachable
+
+
+
+These examples reiterate the fdiv example: a store "of" an undefined value
+can be assumed to not have any effect: we can assume that the value is
+overwritten with bits that happen to match what was already there. However, a
+store "to" an undefined location could clobber arbitrary memory, therefore, it
+has undefined behavior.
+
From gohman at apple.com Mon Sep 7 18:47:14 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 23:47:14 -0000
Subject: [llvm-commits] [llvm] r81171 - in /llvm/trunk:
lib/CodeGen/SelectionDAG/FastISel.cpp test/CodeGen/X86/fast-isel-fneg.ll
Message-ID: <200909072347.n87NlEv9020080@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 18:47:14 2009
New Revision: 81171
URL: http://llvm.org/viewvc/llvm-project?rev=81171&view=rev
Log:
Fix a thinko: When lowering fneg with xor, bitcast the operands
from floating-point to integer first, and bitcast the result
back to floating-point. Previously, this test was passing by
falling back to SelectionDAG lowering. The resulting code isn't
as nice, but it's correct and CodeGen now stays on the fast path.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=81171&r1=81170&r2=81171&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Mon Sep 7 18:47:14 2009
@@ -615,12 +615,25 @@
unsigned OpReg = getRegForValue(BinaryOperator::getFNegArgument(I));
if (OpReg == 0) return false;
- // Twiddle the sign bit with xor.
+ // Bitcast the value to integer, twiddle the sign bit with xor,
+ // and then bitcast it back to floating-point.
EVT VT = TLI.getValueType(I->getType());
if (VT.getSizeInBits() > 64) return false;
- unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISD::XOR, OpReg,
- UINT64_C(1) << (VT.getSizeInBits()-1),
- VT.getSimpleVT());
+ EVT IntVT = EVT::getIntegerVT(I->getContext(), VT.getSizeInBits());
+
+ unsigned IntReg = FastEmit_r(VT.getSimpleVT(), IntVT.getSimpleVT(),
+ ISD::BIT_CONVERT, OpReg);
+ if (IntReg == 0)
+ return false;
+
+ unsigned IntResultReg = FastEmit_ri_(IntVT.getSimpleVT(), ISD::XOR, IntReg,
+ UINT64_C(1) << (VT.getSizeInBits()-1),
+ IntVT.getSimpleVT());
+ if (IntResultReg == 0)
+ return false;
+
+ unsigned ResultReg = FastEmit_r(IntVT.getSimpleVT(), VT.getSimpleVT(),
+ ISD::BIT_CONVERT, IntResultReg);
if (ResultReg == 0)
return false;
Modified: llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll?rev=81171&r1=81170&r2=81171&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-fneg.ll Mon Sep 7 18:47:14 2009
@@ -1,14 +1,14 @@
-; RUN: llvm-as < %s | llc -fast-isel -march=x86-64 | FileCheck %s
+; RUN: llvm-as < %s | llc -fast-isel -fast-isel-abort -march=x86-64 | FileCheck %s
; CHECK: doo:
-; CHECK: xorpd
+; CHECK: xor
define double @doo(double %x) nounwind {
%y = fsub double -0.0, %x
ret double %y
}
; CHECK: foo:
-; CHECK: xorps
+; CHECK: xor
define float @foo(float %x) nounwind {
%y = fsub float -0.0, %x
ret float %y
From gohman at apple.com Mon Sep 7 18:54:19 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 23:54:19 -0000
Subject: [llvm-commits] [llvm] r81172 - in /llvm/trunk:
include/llvm/Constants.h include/llvm/InstrTypes.h
include/llvm/Instructions.h include/llvm/Operator.h include/llvm/Value.h
lib/AsmParser/LLParser.cpp lib/Bitcode/Reader/BitcodeReader.cpp
lib/Transforms/Scalar/InstructionCombining.cpp lib/VMCore/Constants.cpp
lib/VMCore/ConstantsContext.h lib/VMCore/Instructions.cpp
test/Assembler/flags-plain.ll test/Assembler/flags-reversed.ll
test/Assembler/flags-signed.ll test/Assembler/flags-unsigned.ll
test/Assembler/flags.ll
Message-ID: <200909072354.n87NsKJ8020974@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 18:54:19 2009
New Revision: 81172
URL: http://llvm.org/viewvc/llvm-project?rev=81172&view=rev
Log:
Reappy r80998, now that the GlobalOpt bug that it exposed on MiniSAT is fixed.
Removed:
llvm/trunk/test/Assembler/flags-plain.ll
llvm/trunk/test/Assembler/flags-reversed.ll
llvm/trunk/test/Assembler/flags-signed.ll
llvm/trunk/test/Assembler/flags-unsigned.ll
Modified:
llvm/trunk/include/llvm/Constants.h
llvm/trunk/include/llvm/InstrTypes.h
llvm/trunk/include/llvm/Instructions.h
llvm/trunk/include/llvm/Operator.h
llvm/trunk/include/llvm/Value.h
llvm/trunk/lib/AsmParser/LLParser.cpp
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/lib/VMCore/Constants.cpp
llvm/trunk/lib/VMCore/ConstantsContext.h
llvm/trunk/lib/VMCore/Instructions.cpp
llvm/trunk/test/Assembler/flags.ll
Modified: llvm/trunk/include/llvm/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Constants.h (original)
+++ llvm/trunk/include/llvm/Constants.h Mon Sep 7 18:54:19 2009
@@ -571,13 +571,17 @@
// These private methods are used by the type resolution code to create
// ConstantExprs in intermediate forms.
static Constant *getTy(const Type *Ty, unsigned Opcode,
- Constant *C1, Constant *C2);
+ Constant *C1, Constant *C2,
+ unsigned Flags = 0);
static Constant *getCompareTy(unsigned short pred, Constant *C1,
Constant *C2);
static Constant *getSelectTy(const Type *Ty,
Constant *C1, Constant *C2, Constant *C3);
static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
Value* const *Idxs, unsigned NumIdxs);
+ static Constant *getInBoundsGetElementPtrTy(const Type *Ty, Constant *C,
+ Value* const *Idxs,
+ unsigned NumIdxs);
static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
Constant *Idx);
static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
@@ -718,7 +722,8 @@
/// get - Return a binary or shift operator constant expression,
/// folding if possible.
///
- static Constant *get(unsigned Opcode, Constant *C1, Constant *C2);
+ static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
+ unsigned Flags = 0);
/// @brief Return an ICmp or FCmp comparison operator constant expression.
static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
Modified: llvm/trunk/include/llvm/InstrTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InstrTypes.h (original)
+++ llvm/trunk/include/llvm/InstrTypes.h Mon Sep 7 18:54:19 2009
@@ -200,19 +200,19 @@
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
const Twine &Name = "") {
BinaryOperator *BO = CreateAdd(V1, V2, Name);
- cast(BO)->setHasNoSignedWrap(true);
+ BO->setHasNoSignedWrap(true);
return BO;
}
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
const Twine &Name, BasicBlock *BB) {
BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
- cast(BO)->setHasNoSignedWrap(true);
+ BO->setHasNoSignedWrap(true);
return BO;
}
static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
const Twine &Name, Instruction *I) {
BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
- cast(BO)->setHasNoSignedWrap(true);
+ BO->setHasNoSignedWrap(true);
return BO;
}
@@ -221,19 +221,19 @@
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
const Twine &Name = "") {
BinaryOperator *BO = CreateSDiv(V1, V2, Name);
- cast(BO)->setIsExact(true);
+ BO->setIsExact(true);
return BO;
}
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
const Twine &Name, BasicBlock *BB) {
BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
- cast(BO)->setIsExact(true);
+ BO->setIsExact(true);
return BO;
}
static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
const Twine &Name, Instruction *I) {
BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
- cast(BO)->setIsExact(true);
+ BO->setIsExact(true);
return BO;
}
@@ -287,6 +287,21 @@
///
bool swapOperands();
+ /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction,
+ /// which must be an operator which supports this flag. See LangRef.html
+ /// for the meaning of this flag.
+ void setHasNoUnsignedWrap(bool);
+
+ /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction,
+ /// which must be an operator which supports this flag. See LangRef.html
+ /// for the meaning of this flag.
+ void setHasNoSignedWrap(bool);
+
+ /// setIsExact - Set or clear the exact flag on this instruction,
+ /// which must be an operator which supports this flag. See LangRef.html
+ /// for the meaning of this flag.
+ void setIsExact(bool);
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const BinaryOperator *) { return true; }
static inline bool classof(const Instruction *I) {
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Mon Sep 7 18:54:19 2009
@@ -496,7 +496,7 @@
Instruction *InsertBefore = 0) {
GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
NameStr, InsertBefore);
- cast(GEP)->setIsInBounds(true);
+ GEP->setIsInBounds(true);
return GEP;
}
template
@@ -507,21 +507,21 @@
BasicBlock *InsertAtEnd) {
GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
NameStr, InsertAtEnd);
- cast(GEP)->setIsInBounds(true);
+ GEP->setIsInBounds(true);
return GEP;
}
static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
const Twine &NameStr = "",
Instruction *InsertBefore = 0) {
GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
- cast(GEP)->setIsInBounds(true);
+ GEP->setIsInBounds(true);
return GEP;
}
static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
- cast(GEP)->setIsInBounds(true);
+ GEP->setIsInBounds(true);
return GEP;
}
@@ -602,6 +602,10 @@
/// a constant offset between them.
bool hasAllConstantIndices() const;
+ /// setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
+ /// See LangRef.html for the meaning of inbounds on a getelementptr.
+ void setIsInBounds(bool);
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GetElementPtrInst *) { return true; }
static inline bool classof(const Instruction *I) {
Modified: llvm/trunk/include/llvm/Operator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Operator.h?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Operator.h (original)
+++ llvm/trunk/include/llvm/Operator.h Mon Sep 7 18:54:19 2009
@@ -21,6 +21,8 @@
namespace llvm {
class GetElementPtrInst;
+class BinaryOperator;
+class ConstantExpr;
/// Operator - This is a utility class that provides an abstraction for the
/// common functionality between Instructions and ConstantExprs.
@@ -67,24 +69,37 @@
/// despite that operator having the potential for overflow.
///
class OverflowingBinaryOperator : public Operator {
+public:
+ enum {
+ NoUnsignedWrap = (1 << 0),
+ NoSignedWrap = (1 << 1)
+ };
+
+private:
~OverflowingBinaryOperator(); // do not implement
+
+ friend class BinaryOperator;
+ friend class ConstantExpr;
+ void setHasNoUnsignedWrap(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
+ }
+ void setHasNoSignedWrap(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
+ }
+
public:
/// hasNoUnsignedWrap - Test whether this operation is known to never
/// undergo unsigned overflow, aka the nuw property.
bool hasNoUnsignedWrap() const {
- return SubclassOptionalData & (1 << 0);
- }
- void setHasNoUnsignedWrap(bool B) {
- SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
+ return SubclassOptionalData & NoUnsignedWrap;
}
/// hasNoSignedWrap - Test whether this operation is known to never
/// undergo signed overflow, aka the nsw property.
bool hasNoSignedWrap() const {
- return SubclassOptionalData & (1 << 1);
- }
- void setHasNoSignedWrap(bool B) {
- SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1);
+ return SubclassOptionalData & NoSignedWrap;
}
static inline bool classof(const OverflowingBinaryOperator *) { return true; }
@@ -161,15 +176,25 @@
/// SDivOperator - An Operator with opcode Instruction::SDiv.
///
class SDivOperator : public Operator {
+public:
+ enum {
+ IsExact = (1 << 0)
+ };
+
+private:
~SDivOperator(); // do not implement
+
+ friend class BinaryOperator;
+ friend class ConstantExpr;
+ void setIsExact(bool B) {
+ SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
+ }
+
public:
/// isExact - Test whether this division is known to be exact, with
/// zero remainder.
bool isExact() const {
- return SubclassOptionalData & (1 << 0);
- }
- void setIsExact(bool B) {
- SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
+ return SubclassOptionalData & IsExact;
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -187,15 +212,24 @@
};
class GEPOperator : public Operator {
+ enum {
+ IsInBounds = (1 << 0)
+ };
+
~GEPOperator(); // do not implement
+
+ friend class GetElementPtrInst;
+ friend class ConstantExpr;
+ void setIsInBounds(bool B) {
+ SubclassOptionalData =
+ (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
+ }
+
public:
/// isInBounds - Test whether this is an inbounds GEP, as defined
/// by LangRef.html.
bool isInBounds() const {
- return SubclassOptionalData & (1 << 0);
- }
- void setIsInBounds(bool B) {
- SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
+ return SubclassOptionalData & IsInBounds;
}
inline op_iterator idx_begin() { return op_begin()+1; }
Modified: llvm/trunk/include/llvm/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Value.h?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Value.h (original)
+++ llvm/trunk/include/llvm/Value.h Mon Sep 7 18:54:19 2009
@@ -146,12 +146,6 @@
// Only use when in type resolution situations!
void uncheckedReplaceAllUsesWith(Value *V);
- /// clearOptionalData - Clear any optional optimization data from this Value.
- /// Transformation passes must call this method whenever changing the IR
- /// in a way that would affect the values produced by this Value, unless
- /// it takes special care to ensure correctness in some other way.
- void clearOptionalData() { SubclassOptionalData = 0; }
-
//----------------------------------------------------------------------
// Methods for handling the chain of uses of this Value.
//
@@ -240,6 +234,13 @@
return SubclassID;
}
+ /// getRawSubclassOptionalData - Return the raw optional flags value
+ /// contained in this value. This should only be used when testing two
+ /// Values for equivalence.
+ unsigned getRawSubclassOptionalData() const {
+ return SubclassOptionalData;
+ }
+
/// hasSameSubclassOptionalData - Test whether the optional flags contained
/// in this value are equal to the optional flags in the given value.
bool hasSameSubclassOptionalData(const Value *V) const {
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Sep 7 18:54:19 2009
@@ -2095,13 +2095,11 @@
if (!Val0->getType()->isIntOrIntVector() &&
!Val0->getType()->isFPOrFPVector())
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
- Constant *C = ConstantExpr::get(Opc, Val0, Val1);
- if (NUW)
- cast(C)->setHasNoUnsignedWrap(true);
- if (NSW)
- cast(C)->setHasNoSignedWrap(true);
- if (Exact)
- cast(C)->setIsExact(true);
+ unsigned Flags = 0;
+ if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+ if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap;
+ if (Exact) Flags |= SDivOperator::IsExact;
+ Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
ID.ConstantVal = C;
ID.Kind = ValID::t_Constant;
return false;
@@ -2157,10 +2155,12 @@
(Value**)(Elts.data() + 1),
Elts.size() - 1))
return Error(ID.Loc, "invalid indices for getelementptr");
- ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
- Elts.data() + 1, Elts.size() - 1);
- if (InBounds)
- cast(ID.ConstantVal)->setIsInBounds(true);
+ ID.ConstantVal = InBounds ?
+ ConstantExpr::getInBoundsGetElementPtr(Elts[0],
+ Elts.data() + 1,
+ Elts.size() - 1) :
+ ConstantExpr::getGetElementPtr(Elts[0],
+ Elts.data() + 1, Elts.size() - 1);
} else if (Opc == Instruction::Select) {
if (Elts.size() != 3)
return Error(ID.Loc, "expected three operands to select");
@@ -2681,9 +2681,9 @@
return Error(ModifierLoc, "nsw only applies to integer operations");
}
if (NUW)
- cast(Inst)->setHasNoUnsignedWrap(true);
+ cast(Inst)->setHasNoUnsignedWrap(true);
if (NSW)
- cast(Inst)->setHasNoSignedWrap(true);
+ cast(Inst)->setHasNoSignedWrap(true);
}
return Result;
}
@@ -2698,7 +2698,7 @@
bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
if (!Result)
if (Exact)
- cast(Inst)->setIsExact(true);
+ cast(Inst)->setIsExact(true);
return Result;
}
@@ -3501,7 +3501,7 @@
return Error(Loc, "invalid getelementptr indices");
Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
if (InBounds)
- cast(Inst)->setIsInBounds(true);
+ cast(Inst)->setIsInBounds(true);
return false;
}
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Sep 7 18:54:19 2009
@@ -883,19 +883,6 @@
return false;
}
-static void SetOptimizationFlags(Value *V, uint64_t Flags) {
- if (OverflowingBinaryOperator *OBO =
- dyn_cast(V)) {
- if (Flags & (1 << bitc::OBO_NO_SIGNED_WRAP))
- OBO->setHasNoSignedWrap(true);
- if (Flags & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
- OBO->setHasNoUnsignedWrap(true);
- } else if (SDivOperator *Div = dyn_cast(V)) {
- if (Flags & (1 << bitc::SDIV_EXACT))
- Div->setIsExact(true);
- }
-}
-
bool BitcodeReader::ParseConstants() {
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
return Error("Malformed block record");
@@ -1047,10 +1034,22 @@
} else {
Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
- V = ConstantExpr::get(Opc, LHS, RHS);
+ unsigned Flags = 0;
+ if (Record.size() >= 4) {
+ if (Opc == Instruction::Add ||
+ Opc == Instruction::Sub ||
+ Opc == Instruction::Mul) {
+ if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+ Flags |= OverflowingBinaryOperator::NoSignedWrap;
+ if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+ Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
+ } else if (Opc == Instruction::SDiv) {
+ if (Record[3] & (1 << bitc::SDIV_EXACT))
+ Flags |= SDivOperator::IsExact;
+ }
+ }
+ V = ConstantExpr::get(Opc, LHS, RHS, Flags);
}
- if (Record.size() >= 4)
- SetOptimizationFlags(V, Record[3]);
break;
}
case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
@@ -1075,10 +1074,12 @@
if (!ElTy) return Error("Invalid CE_GEP record");
Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
}
- V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1],
- Elts.size()-1);
if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
- cast(V)->setIsInBounds(true);
+ V = ConstantExpr::getInBoundsGetElementPtr(Elts[0], &Elts[1],
+ Elts.size()-1);
+ else
+ V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1],
+ Elts.size()-1);
break;
}
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
@@ -1610,8 +1611,19 @@
int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
if (Opc == -1) return Error("Invalid BINOP record");
I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
- if (OpNum < Record.size())
- SetOptimizationFlags(I, Record[3]);
+ if (OpNum < Record.size()) {
+ if (Opc == Instruction::Add ||
+ Opc == Instruction::Sub ||
+ Opc == Instruction::Mul) {
+ if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
+ cast(I)->setHasNoSignedWrap(true);
+ if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
+ cast(I)->setHasNoUnsignedWrap(true);
+ } else if (Opc == Instruction::SDiv) {
+ if (Record[3] & (1 << bitc::SDIV_EXACT))
+ cast(I)->setIsExact(true);
+ }
+ }
break;
}
case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
@@ -1645,7 +1657,7 @@
I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
- cast(I)->setIsInBounds(true);
+ cast(I)->setIsInBounds(true);
break;
}
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 7 18:54:19 2009
@@ -8086,11 +8086,11 @@
// If we were able to index down into an element, create the GEP
// and bitcast the result. This eliminates one bitcast, potentially
// two.
- Value *NGEP = Builder->CreateGEP(OrigBase, NewIndices.begin(),
- NewIndices.end());
+ Value *NGEP = cast(GEP)->isInBounds() ?
+ Builder->CreateInBoundsGEP(OrigBase,
+ NewIndices.begin(), NewIndices.end()) :
+ Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
NGEP->takeName(GEP);
- if (isa(NGEP) && cast(GEP)->isInBounds())
- cast(NGEP)->setIsInBounds(true);
if (isa(CI))
return new BitCastInst(NGEP, CI.getType());
@@ -8805,11 +8805,8 @@
// If we found a path from the src to dest, create the getelementptr now.
if (SrcElTy == DstElTy) {
SmallVector Idxs(NumZeros+1, ZeroUInt);
- Instruction *GEP = GetElementPtrInst::Create(Src,
- Idxs.begin(), Idxs.end(), "",
- ((Instruction*) NULL));
- cast(GEP)->setIsInBounds(true);
- return GEP;
+ return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(), "",
+ ((Instruction*) NULL));
}
}
@@ -10481,12 +10478,11 @@
}
Value *Base = FixedOperands[0];
- GetElementPtrInst *GEP =
+ return cast(FirstInst)->isInBounds() ?
+ GetElementPtrInst::CreateInBounds(Base, FixedOperands.begin()+1,
+ FixedOperands.end()) :
GetElementPtrInst::Create(Base, FixedOperands.begin()+1,
FixedOperands.end());
- if (cast(FirstInst)->isInBounds())
- cast(GEP)->setIsInBounds(true);
- return GEP;
}
@@ -10889,14 +10885,13 @@
Indices.append(GEP.idx_begin()+1, GEP.idx_end());
}
- if (!Indices.empty()) {
- GetElementPtrInst *NewGEP =
+ if (!Indices.empty())
+ return (cast(&GEP)->isInBounds() &&
+ Src->isInBounds()) ?
+ GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
+ Indices.end(), GEP.getName()) :
GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
Indices.end(), GEP.getName());
- if (cast(&GEP)->isInBounds() && Src->isInBounds())
- cast(NewGEP)->setIsInBounds(true);
- return NewGEP;
- }
}
// Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
@@ -10926,12 +10921,11 @@
if (CATy->getElementType() == XTy->getElementType()) {
// -> GEP i8* X, ...
SmallVector Indices(GEP.idx_begin()+1, GEP.idx_end());
- GetElementPtrInst *NewGEP =
+ return cast(&GEP)->isInBounds() ?
+ GetElementPtrInst::CreateInBounds(X, Indices.begin(), Indices.end(),
+ GEP.getName()) :
GetElementPtrInst::Create(X, Indices.begin(), Indices.end(),
GEP.getName());
- if (cast(&GEP)->isInBounds())
- cast(NewGEP)->setIsInBounds(true);
- return NewGEP;
}
if (const ArrayType *XATy = dyn_cast(XTy->getElementType())){
@@ -10959,10 +10953,9 @@
Value *Idx[2];
Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
Idx[1] = GEP.getOperand(1);
- Value *NewGEP =
+ Value *NewGEP = cast(&GEP)->isInBounds() ?
+ Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
- if (cast(&GEP)->isInBounds())
- cast(NewGEP)->setIsInBounds(true);
// V and GEP are both pointer types --> BitCast
return new BitCastInst(NewGEP, GEP.getType());
}
@@ -11019,9 +11012,9 @@
Value *Idx[2];
Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
Idx[1] = NewIdx;
- Value *NewGEP = Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
- if (cast(&GEP)->isInBounds())
- cast(NewGEP)->setIsInBounds(true);
+ Value *NewGEP = cast(&GEP)->isInBounds() ?
+ Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
+ Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
// The NewGEP must be pointer typed, so must the old one -> BitCast
return new BitCastInst(NewGEP, GEP.getType());
}
@@ -11069,10 +11062,11 @@
const Type *InTy =
cast(BCI->getOperand(0)->getType())->getElementType();
if (FindElementAtOffset(InTy, Offset, NewIndices, TD, Context)) {
- Value *NGEP = Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
- NewIndices.end());
- if (cast(&GEP)->isInBounds())
- cast(NGEP)->setIsInBounds(true);
+ Value *NGEP = cast(&GEP)->isInBounds() ?
+ Builder->CreateInBoundsGEP(BCI->getOperand(0), NewIndices.begin(),
+ NewIndices.end()) :
+ Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
+ NewIndices.end());
if (NGEP->getType() == GEP.getType())
return ReplaceInstUsesWith(GEP, NGEP);
@@ -11115,9 +11109,8 @@
Value *Idx[2];
Idx[0] = NullIdx;
Idx[1] = NullIdx;
- Value *V = GetElementPtrInst::Create(New, Idx, Idx + 2,
- New->getName()+".sub", It);
- cast(V)->setIsInBounds(true);
+ Value *V = GetElementPtrInst::CreateInBounds(New, Idx, Idx + 2,
+ New->getName()+".sub", It);
// Now make everything use the getelementptr instead of the original
// allocation.
@@ -11486,11 +11479,9 @@
// SIOp0 is a pointer to aggregate and this is a store to the first field,
// emit a GEP to index into its first field.
- if (!NewGEPIndices.empty()) {
- CastOp = IC.Builder->CreateGEP(CastOp, NewGEPIndices.begin(),
- NewGEPIndices.end());
- cast(CastOp)->setIsInBounds(true);
- }
+ if (!NewGEPIndices.empty())
+ CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices.begin(),
+ NewGEPIndices.end());
NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
SIOp0->getName()+".c");
Modified: llvm/trunk/lib/VMCore/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Constants.cpp (original)
+++ llvm/trunk/lib/VMCore/Constants.cpp Mon Sep 7 18:54:19 2009
@@ -632,21 +632,13 @@
}
Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
- Constant *C = getAdd(C1, C2);
- // Set nsw attribute, assuming constant folding didn't eliminate the
- // Add.
- if (AddOperator *Add = dyn_cast(C))
- Add->setHasNoSignedWrap(true);
- return C;
+ return getTy(C1->getType(), Instruction::Add, C1, C2,
+ OverflowingBinaryOperator::NoSignedWrap);
}
Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
- Constant *C = getSDiv(C1, C2);
- // Set exact attribute, assuming constant folding didn't eliminate the
- // SDiv.
- if (SDivOperator *SDiv = dyn_cast(C))
- SDiv->setIsExact(true);
- return C;
+ return getTy(C1->getType(), Instruction::SDiv, C1, C2,
+ SDivOperator::IsExact);
}
// Utility function for determining if a ConstantExpr is a CastOp or not. This
@@ -729,15 +721,19 @@
for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
Ops[i-1] = getOperand(i);
if (OpNo == 0)
- return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
+ return cast(this)->isInBounds() ?
+ ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) :
+ ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
Ops[OpNo-1] = Op;
- return ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
+ return cast(this)->isInBounds() ?
+ ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) :
+ ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
}
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
Op0 = (OpNo == 0) ? Op : getOperand(0);
Op1 = (OpNo == 1) ? Op : getOperand(1);
- return ConstantExpr::get(getOpcode(), Op0, Op1);
+ return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData);
}
}
@@ -779,13 +775,15 @@
case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
case Instruction::GetElementPtr:
- return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
+ return cast(this)->isInBounds() ?
+ ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) :
+ ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
case Instruction::ICmp:
case Instruction::FCmp:
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
- return ConstantExpr::get(getOpcode(), Ops[0], Ops[1]);
+ return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData);
}
}
@@ -1031,8 +1029,9 @@
Operands.reserve(CE->getNumOperands());
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
Operands.push_back(cast(CE->getOperand(i)));
- return ExprMapKeyType(CE->getOpcode(), Operands,
+ return ExprMapKeyType(CE->getOpcode(), Operands,
CE->isCompare() ? CE->getPredicate() : 0,
+ CE->getRawSubclassOptionalData(),
CE->hasIndices() ?
CE->getIndices() : SmallVector());
}
@@ -1280,7 +1279,8 @@
}
Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
- Constant *C1, Constant *C2) {
+ Constant *C1, Constant *C2,
+ unsigned Flags) {
// Check the operands for consistency first
assert(Opcode >= Instruction::BinaryOpsBegin &&
Opcode < Instruction::BinaryOpsEnd &&
@@ -1294,7 +1294,7 @@
return FC; // Fold a few common cases...
std::vector argVec(1, C1); argVec.push_back(C2);
- ExprMapKeyType Key(Opcode, argVec);
+ ExprMapKeyType Key(Opcode, argVec, 0, Flags);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
@@ -1322,7 +1322,8 @@
}
}
-Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
+Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
+ unsigned Flags) {
// API compatibility: Adjust integer opcodes to floating-point opcodes.
if (C1->getType()->isFPOrFPVector()) {
if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
@@ -1387,7 +1388,7 @@
}
#endif
- return getTy(C1->getType(), Opcode, C1, C2);
+ return getTy(C1->getType(), Opcode, C1, C2, Flags);
}
Constant* ConstantExpr::getSizeOf(const Type* Ty) {
@@ -1481,6 +1482,36 @@
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
+Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
+ Constant *C,
+ Value* const *Idxs,
+ unsigned NumIdx) {
+ assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
+ Idxs+NumIdx) ==
+ cast(ReqTy)->getElementType() &&
+ "GEP indices invalid!");
+
+ if (Constant *FC = ConstantFoldGetElementPtr(
+ ReqTy->getContext(), C, (Constant**)Idxs, NumIdx))
+ return FC; // Fold a few common cases...
+
+ assert(isa(C->getType()) &&
+ "Non-pointer type for constant GetElementPtr expression");
+ // Look up the constant in the table first to ensure uniqueness
+ std::vector ArgVec;
+ ArgVec.reserve(NumIdx+1);
+ ArgVec.push_back(C);
+ for (unsigned i = 0; i != NumIdx; ++i)
+ ArgVec.push_back(cast(Idxs[i]));
+ const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
+ GEPOperator::IsInBounds);
+
+ LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
+
+ // Implicitly locked.
+ return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
+}
+
Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
unsigned NumIdx) {
// Get the result type of the getelementptr!
@@ -1494,12 +1525,12 @@
Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
Value* const *Idxs,
unsigned NumIdx) {
- Constant *Result = getGetElementPtr(C, Idxs, NumIdx);
- // Set in bounds attribute, assuming constant folding didn't eliminate the
- // GEP.
- if (GEPOperator *GEP = dyn_cast(Result))
- GEP->setIsInBounds(true);
- return Result;
+ // Get the result type of the getelementptr!
+ const Type *Ty =
+ GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
+ assert(Ty && "GEP indices invalid!");
+ unsigned As = cast(C->getType())->getAddressSpace();
+ return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
}
Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
@@ -2104,7 +2135,7 @@
Constant *C2 = getOperand(1);
if (C1 == From) C1 = To;
if (C2 == From) C2 = To;
- Replacement = ConstantExpr::get(getOpcode(), C1, C2);
+ Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData);
} else {
llvm_unreachable("Unknown ConstantExpr type!");
return;
Modified: llvm/trunk/lib/VMCore/ConstantsContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantsContext.h?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantsContext.h (original)
+++ llvm/trunk/lib/VMCore/ConstantsContext.h Mon Sep 7 18:54:19 2009
@@ -53,10 +53,12 @@
void *operator new(size_t s) {
return User::operator new(s, 2);
}
- BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
+ BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
+ unsigned Flags)
: ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
Op<0>() = C1;
Op<1>() = C2;
+ SubclassOptionalData = Flags;
}
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -206,9 +208,12 @@
public:
static GetElementPtrConstantExpr *Create(Constant *C,
const std::vector&IdxList,
- const Type *DestTy) {
- return
+ const Type *DestTy,
+ unsigned Flags) {
+ GetElementPtrConstantExpr *Result =
new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
+ Result->SubclassOptionalData = Flags;
+ return Result;
}
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -291,26 +296,32 @@
ExprMapKeyType(unsigned opc,
const std::vector &ops,
- unsigned short pred = 0,
+ unsigned short flags = 0,
+ unsigned short optionalflags = 0,
const IndexList &inds = IndexList())
- : opcode(opc), predicate(pred), operands(ops), indices(inds) {}
- uint16_t opcode;
- uint16_t predicate;
+ : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
+ operands(ops), indices(inds) {}
+ uint8_t opcode;
+ uint8_t subclassoptionaldata;
+ uint16_t subclassdata;
std::vector operands;
IndexList indices;
bool operator==(const ExprMapKeyType& that) const {
return this->opcode == that.opcode &&
- this->predicate == that.predicate &&
+ this->subclassdata == that.subclassdata &&
+ this->subclassoptionaldata == that.subclassoptionaldata &&
this->operands == that.operands &&
this->indices == that.indices;
}
bool operator<(const ExprMapKeyType & that) const {
- return this->opcode < that.opcode ||
- (this->opcode == that.opcode && this->predicate < that.predicate) ||
- (this->opcode == that.opcode && this->predicate == that.predicate &&
- this->operands < that.operands) ||
- (this->opcode == that.opcode && this->predicate == that.predicate &&
- this->operands == that.operands && this->indices < that.indices);
+ if (this->opcode != that.opcode) return this->opcode < that.opcode;
+ if (this->operands != that.operands) return this->operands < that.operands;
+ if (this->subclassdata != that.subclassdata)
+ return this->subclassdata < that.subclassdata;
+ if (this->subclassoptionaldata != that.subclassoptionaldata)
+ return this->subclassoptionaldata < that.subclassoptionaldata;
+ if (this->indices != that.indices) return this->indices < that.indices;
+ return false;
}
bool operator!=(const ExprMapKeyType& that) const {
@@ -354,7 +365,8 @@
return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
if ((V.opcode >= Instruction::BinaryOpsBegin &&
V.opcode < Instruction::BinaryOpsEnd))
- return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
+ return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
+ V.subclassoptionaldata);
if (V.opcode == Instruction::Select)
return new SelectConstantExpr(V.operands[0], V.operands[1],
V.operands[2]);
@@ -373,17 +385,18 @@
return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
if (V.opcode == Instruction::GetElementPtr) {
std::vector IdxList(V.operands.begin()+1, V.operands.end());
- return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
+ return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
+ V.subclassoptionaldata);
}
// The compare instructions are weird. We have to encode the predicate
// value and it is combined with the instruction opcode by multiplying
// the opcode by one hundred. We must decode this to get the predicate.
if (V.opcode == Instruction::ICmp)
- return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate,
+ return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
V.operands[0], V.operands[1]);
if (V.opcode == Instruction::FCmp)
- return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate,
+ return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
V.operands[0], V.operands[1]);
llvm_unreachable("Invalid ConstantExpr!");
return 0;
Modified: llvm/trunk/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Sep 7 18:54:19 2009
@@ -1171,6 +1171,9 @@
return true;
}
+void GetElementPtrInst::setIsInBounds(bool B) {
+ cast(this)->setIsInBounds(B);
+}
//===----------------------------------------------------------------------===//
// ExtractElementInst Implementation
@@ -1716,6 +1719,18 @@
return false;
}
+void BinaryOperator::setHasNoUnsignedWrap(bool b) {
+ cast(this)->setHasNoUnsignedWrap(b);
+}
+
+void BinaryOperator::setHasNoSignedWrap(bool b) {
+ cast(this)->setHasNoSignedWrap(b);
+}
+
+void BinaryOperator::setIsExact(bool b) {
+ cast(this)->setIsExact(b);
+}
+
//===----------------------------------------------------------------------===//
// CastInst Class
//===----------------------------------------------------------------------===//
Removed: llvm/trunk/test/Assembler/flags-plain.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-plain.ll?rev=81171&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/flags-plain.ll (original)
+++ llvm/trunk/test/Assembler/flags-plain.ll (removed)
@@ -1,28 +0,0 @@
-; RUN: llvm-as < %s | llvm-dis | FileCheck %s
-
- at addr = external global i64
-
-define i64 @add_plain_ce() {
-; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sub_plain_ce() {
-; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @mul_plain_ce() {
-; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sdiv_plain_ce() {
-; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64* @gep_plain_ce() {
-; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
- ret i64* getelementptr (i64* @addr, i64 171)
-}
Removed: llvm/trunk/test/Assembler/flags-reversed.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-reversed.ll?rev=81171&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/flags-reversed.ll (original)
+++ llvm/trunk/test/Assembler/flags-reversed.ll (removed)
@@ -1,18 +0,0 @@
-; RUN: llvm-as < %s | llvm-dis | FileCheck %s
-
- at addr = external global i64
-
-define i64 @add_both_reversed_ce() {
-; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sub_both_reversed_ce() {
-; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @mul_both_reversed_ce() {
-; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
Removed: llvm/trunk/test/Assembler/flags-signed.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-signed.ll?rev=81171&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/flags-signed.ll (original)
+++ llvm/trunk/test/Assembler/flags-signed.ll (removed)
@@ -1,18 +0,0 @@
-; RUN: llvm-as < %s | llvm-dis | FileCheck %s
-
- at addr = external global i64
-
-define i64 @add_signed_ce() {
-; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sub_signed_ce() {
-; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @mul_signed_ce() {
-; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
Removed: llvm/trunk/test/Assembler/flags-unsigned.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-unsigned.ll?rev=81171&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/flags-unsigned.ll (original)
+++ llvm/trunk/test/Assembler/flags-unsigned.ll (removed)
@@ -1,18 +0,0 @@
-; RUN: llvm-as < %s | llvm-dis | FileCheck %s
-
- at addr = external global i64
-
-define i64 @add_unsigned_ce() {
-; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @sub_unsigned_ce() {
-; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
-
-define i64 @mul_unsigned_ce() {
-; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
- ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
-}
Modified: llvm/trunk/test/Assembler/flags.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags.ll?rev=81172&r1=81171&r2=81172&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/flags.ll (original)
+++ llvm/trunk/test/Assembler/flags.ll Mon Sep 7 18:54:19 2009
@@ -141,4 +141,72 @@
ret i64* getelementptr inbounds (i64* @addr, i64 171)
}
+define i64 @add_plain_ce() {
+; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sub_plain_ce() {
+; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @mul_plain_ce() {
+; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sdiv_plain_ce() {
+; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64* @gep_plain_ce() {
+; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
+ ret i64* getelementptr (i64* @addr, i64 171)
+}
+
+define i64 @add_both_reversed_ce() {
+; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sub_both_reversed_ce() {
+; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+define i64 @mul_both_reversed_ce() {
+; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @add_signed_ce() {
+; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sub_signed_ce() {
+; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @mul_signed_ce() {
+; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @add_unsigned_ce() {
+; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @sub_unsigned_ce() {
+; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
+
+define i64 @mul_unsigned_ce() {
+; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+ ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
+}
From clattner at apple.com Mon Sep 7 18:57:54 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 16:57:54 -0700
Subject: [llvm-commits] [llvm] r81171 - in /llvm/trunk:
lib/CodeGen/SelectionDAG/FastISel.cpp
test/CodeGen/X86/fast-isel-fneg.ll
In-Reply-To: <200909072347.n87NlEv9020080@zion.cs.uiuc.edu>
References: <200909072347.n87NlEv9020080@zion.cs.uiuc.edu>
Message-ID: <5BEC497E-3D9C-4FCC-9636-1CD9200FBE44@apple.com>
On Sep 7, 2009, at 4:47 PM, Dan Gohman wrote:
> Author: djg
> Date: Mon Sep 7 18:47:14 2009
> New Revision: 81171
>
> URL: http://llvm.org/viewvc/llvm-project?rev=81171&view=rev
> Log:
> Fix a thinko: When lowering fneg with xor, bitcast the operands
> from floating-point to integer first, and bitcast the result
> back to floating-point. Previously, this test was passing by
> falling back to SelectionDAG lowering. The resulting code isn't
> as nice, but it's correct and CodeGen now stays on the fast path.
Why not lower to ISD::FNEG?
-Chris
From gohman at apple.com Mon Sep 7 19:00:49 2009
From: gohman at apple.com (Dan Gohman)
Date: Mon, 07 Sep 2009 17:00:49 -0700
Subject: [llvm-commits] [llvm] r80963 - in /llvm/trunk:
include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/FastISel.cpp
test/CodeGen/X86/fast-isel-fneg.ll
In-Reply-To:
References: <200909032253.n83Mrvlj011046@zion.cs.uiuc.edu>
Message-ID: <163C8649-90F7-4D3B-95AE-0FEB5B404BBC@apple.com>
On Sep 7, 2009, at 3:23 PM, Chris Lattner wrote:
>
> On Sep 3, 2009, at 3:53 PM, Dan Gohman wrote:
>
>> Author: djg
>> Date: Thu Sep 3 17:53:57 2009
>> New Revision: 80963
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=80963&view=rev
>> Log:
>> LLVM currently represents floating-point negation as -0.0 - x. Fix
>> FastISel to recognize this pattern and emit a floating-point
>> negation using xor.
>
> ISD::XOR is legal for floating point operands?
Oops, no. This is fixed now.
Dan
From sabre at nondot.org Mon Sep 7 19:06:16 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 00:06:16 -0000
Subject: [llvm-commits] [llvm] r81173 - in /llvm/trunk:
include/llvm/Analysis/ValueTracking.h lib/Analysis/ValueTracking.cpp
Message-ID: <200909080006.n8806GSt022590@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 19:06:16 2009
New Revision: 81173
URL: http://llvm.org/viewvc/llvm-project?rev=81173&view=rev
Log:
add some comments to describe the invariants.
Modified:
llvm/trunk/include/llvm/Analysis/ValueTracking.h
llvm/trunk/lib/Analysis/ValueTracking.cpp
Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=81173&r1=81172&r2=81173&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original)
+++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Mon Sep 7 19:06:16 2009
@@ -29,6 +29,12 @@
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bit sets. This code only analyzes bits in Mask, in order to short-circuit
/// processing.
+ ///
+ /// This function is defined on values with integer type, values with pointer
+ /// type (but only if TD is non-null), and vectors of integers. In the case
+ /// where V is a vector, the mask, known zero, and known one values are the
+ /// same width as the vector element, and the bit is set only if it is true
+ /// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, const APInt &Mask, APInt &KnownZero,
APInt &KnownOne, const TargetData *TD = 0,
unsigned Depth = 0);
@@ -36,6 +42,12 @@
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
/// zero for bits that V cannot have.
+ ///
+ /// This function is defined on values with integer type, values with pointer
+ /// type (but only if TD is non-null), and vectors of integers. In the case
+ /// where V is a vector, the mask, known zero, and known one values are the
+ /// same width as the vector element, and the bit is set only if it is true
+ /// for all of the elements in the vector.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
const TargetData *TD = 0, unsigned Depth = 0);
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=81173&r1=81172&r2=81173&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon Sep 7 19:06:16 2009
@@ -35,6 +35,12 @@
/// optimized based on the contradictory assumption that it is non-zero.
/// Because instcombine aggressively folds operations with undef args anyway,
/// this won't lose us code quality.
+///
+/// This function is defined on values with integer type, values with pointer
+/// type (but only if TD is non-null), and vectors of integers. In the case
+/// where V is a vector, the mask, known zero, and known one values are the
+/// same width as the vector element, and the bit is set only if it is true
+/// for all of the elements in the vector.
void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
APInt &KnownZero, APInt &KnownOne,
const TargetData *TD, unsigned Depth) {
@@ -608,6 +614,12 @@
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be zero
/// for bits that V cannot have.
+///
+/// This function is defined on values with integer type, values with pointer
+/// type (but only if TD is non-null), and vectors of integers. In the case
+/// where V is a vector, the mask, known zero, and known one values are the
+/// same width as the vector element, and the bit is set only if it is true
+/// for all of the elements in the vector.
bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
const TargetData *TD, unsigned Depth) {
APInt KnownZero(Mask.getBitWidth(), 0), KnownOne(Mask.getBitWidth(), 0);
From sabre at nondot.org Mon Sep 7 19:13:52 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 00:13:52 -0000
Subject: [llvm-commits] [llvm] r81174 - in /llvm/trunk:
lib/Analysis/ValueTracking.cpp test/Transforms/InstCombine/crash.ll
Message-ID: <200909080013.n880Dq4m023571@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 19:13:52 2009
New Revision: 81174
URL: http://llvm.org/viewvc/llvm-project?rev=81174&view=rev
Log:
fix ComputeMaskedBits handling of zext/sext/trunc to work with vectors.
This fixes PR4905
Modified:
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/test/Transforms/InstCombine/crash.ll
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=81174&r1=81173&r2=81174&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon Sep 7 19:13:52 2009
@@ -232,12 +232,16 @@
// FALL THROUGH and handle them the same as zext/trunc.
case Instruction::ZExt:
case Instruction::Trunc: {
+ const Type *SrcTy = I->getOperand(0)->getType();
+
+ unsigned SrcBitWidth;
// Note that we handle pointer operands here because of inttoptr/ptrtoint
// which fall through here.
- const Type *SrcTy = I->getOperand(0)->getType();
- unsigned SrcBitWidth = TD ?
- TD->getTypeSizeInBits(SrcTy) :
- SrcTy->getScalarSizeInBits();
+ if (isa(SrcTy))
+ SrcBitWidth = TD->getTypeSizeInBits(SrcTy);
+ else
+ SrcBitWidth = SrcTy->getScalarSizeInBits();
+
APInt MaskIn(Mask);
MaskIn.zextOrTrunc(SrcBitWidth);
KnownZero.zextOrTrunc(SrcBitWidth);
@@ -265,8 +269,7 @@
}
case Instruction::SExt: {
// Compute the bits in the result that are not present in the input.
- const IntegerType *SrcTy = cast(I->getOperand(0)->getType());
- unsigned SrcBitWidth = SrcTy->getBitWidth();
+ unsigned SrcBitWidth = I->getOperand(0)->getType()->getScalarSizeInBits();
APInt MaskIn(Mask);
MaskIn.trunc(SrcBitWidth);
Modified: llvm/trunk/test/Transforms/InstCombine/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/crash.ll?rev=81174&r1=81173&r2=81174&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/crash.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/crash.ll Mon Sep 7 19:13:52 2009
@@ -1,8 +1,8 @@
-; RUN: llvm-as < %s | opt -instcombine | llvm-dis
+; RUN: opt < %s -instcombine | llvm-dis
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i386-apple-darwin10.0"
-define i32 @_Z9model8bitR5Mixeri(i8 %tmp2) ssp {
+define i32 @test0(i8 %tmp2) ssp {
entry:
%tmp3 = zext i8 %tmp2 to i32
%tmp8 = lshr i32 %tmp3, 6
@@ -12,3 +12,22 @@
%tmp12 = xor i32 %tmp11, 0
ret i32 %tmp12
}
+
+; PR4905
+define <2 x i64> @test1(<2 x i64> %x, <2 x i64> %y) nounwind {
+entry:
+ %conv.i94 = bitcast <2 x i64> %y to <4 x i32> ; <<4 x i32>> [#uses=1]
+ %sub.i97 = sub <4 x i32> %conv.i94, undef ; <<4 x i32>> [#uses=1]
+ %conv3.i98 = bitcast <4 x i32> %sub.i97 to <2 x i64> ; <<2 x i64>> [#uses=2]
+ %conv2.i86 = bitcast <2 x i64> %conv3.i98 to <4 x i32> ; <<4 x i32>> [#uses=1]
+ %cmp.i87 = icmp sgt <4 x i32> undef, %conv2.i86 ; <<4 x i1>> [#uses=1]
+ %sext.i88 = sext <4 x i1> %cmp.i87 to <4 x i32> ; <<4 x i32>> [#uses=1]
+ %conv3.i89 = bitcast <4 x i32> %sext.i88 to <2 x i64> ; <<2 x i64>> [#uses=1]
+ %and.i = and <2 x i64> %conv3.i89, %conv3.i98 ; <<2 x i64>> [#uses=1]
+ %or.i = or <2 x i64> zeroinitializer, %and.i ; <<2 x i64>> [#uses=1]
+ %conv2.i43 = bitcast <2 x i64> %or.i to <4 x i32> ; <<4 x i32>> [#uses=1]
+ %sub.i = sub <4 x i32> zeroinitializer, %conv2.i43 ; <<4 x i32>> [#uses=1]
+ %conv3.i44 = bitcast <4 x i32> %sub.i to <2 x i64> ; <<2 x i64>> [#uses=1]
+ ret <2 x i64> %conv3.i44
+}
+
From sabre at nondot.org Mon Sep 7 19:27:15 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 00:27:15 -0000
Subject: [llvm-commits] [llvm] r81175 - in /llvm/trunk:
lib/Transforms/Scalar/MemCpyOptimizer.cpp
test/Transforms/MemCpyOpt/crash.ll
Message-ID: <200909080027.n880RFwr025250@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 19:27:14 2009
New Revision: 81175
URL: http://llvm.org/viewvc/llvm-project?rev=81175&view=rev
Log:
Fix PR4882, by making MemCpyOpt not dereference removed stores to get the
context for the newly created operations.
Patch by Jakub Staszak!
Added:
llvm/trunk/test/Transforms/MemCpyOpt/crash.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=81175&r1=81174&r2=81175&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Mon Sep 7 19:27:14 2009
@@ -340,13 +340,15 @@
bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) {
if (SI->isVolatile()) return false;
+ LLVMContext &Context = SI->getContext();
+
// There are two cases that are interesting for this code to handle: memcpy
// and memset. Right now we only handle memset.
// Ensure that the value being stored is something that can be memset'able a
// byte at a time like "0" or "-1" or any width, as well as things like
// 0xA0A0A0A0 and 0.0.
- Value *ByteVal = isBytewiseValue(SI->getOperand(0), SI->getContext());
+ Value *ByteVal = isBytewiseValue(SI->getOperand(0), Context);
if (!ByteVal)
return false;
@@ -387,8 +389,7 @@
if (NextStore->isVolatile()) break;
// Check to see if this stored value is of the same byte-splattable value.
- if (ByteVal != isBytewiseValue(NextStore->getOperand(0),
- NextStore->getContext()))
+ if (ByteVal != isBytewiseValue(NextStore->getOperand(0), Context))
break;
// Check to see if this store is to a constant offset from the start ptr.
@@ -408,7 +409,6 @@
// store as well. We try to avoid this unless there is at least something
// interesting as a small compile-time optimization.
Ranges.addStore(0, SI);
-
Function *MemSetF = 0;
@@ -432,16 +432,15 @@
BasicBlock::iterator InsertPt = BI;
if (MemSetF == 0) {
- const Type *Ty = Type::getInt64Ty(SI->getContext());
+ const Type *Ty = Type::getInt64Ty(Context);
MemSetF = Intrinsic::getDeclaration(M, Intrinsic::memset, &Ty, 1);
- }
+ }
// Get the starting pointer of the block.
StartPtr = Range.StartPtr;
// Cast the start ptr to be i8* as memset requires.
- const Type *i8Ptr =
- PointerType::getUnqual(Type::getInt8Ty(SI->getContext()));
+ const Type *i8Ptr = PointerType::getUnqual(Type::getInt8Ty(Context));
if (StartPtr->getType() != i8Ptr)
StartPtr = new BitCastInst(StartPtr, i8Ptr, StartPtr->getName(),
InsertPt);
@@ -449,10 +448,9 @@
Value *Ops[] = {
StartPtr, ByteVal, // Start, value
// size
- ConstantInt::get(Type::getInt64Ty(SI->getContext()),
- Range.End-Range.Start),
+ ConstantInt::get(Type::getInt64Ty(Context), Range.End-Range.Start),
// align
- ConstantInt::get(Type::getInt32Ty(SI->getContext()), Range.Alignment)
+ ConstantInt::get(Type::getInt32Ty(Context), Range.Alignment)
};
Value *C = CallInst::Create(MemSetF, Ops, Ops+4, "", InsertPt);
DEBUG(errs() << "Replace stores:\n";
@@ -464,7 +462,8 @@
BBI = BI;
// Zap all the stores.
- for (SmallVector::const_iterator SI = Range.TheStores.begin(),
+ for (SmallVector::const_iterator
+ SI = Range.TheStores.begin(),
SE = Range.TheStores.end(); SI != SE; ++SI)
(*SI)->eraseFromParent();
++NumMemSetInfer;
Added: llvm/trunk/test/Transforms/MemCpyOpt/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/crash.ll?rev=81175&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/MemCpyOpt/crash.ll (added)
+++ llvm/trunk/test/Transforms/MemCpyOpt/crash.ll Mon Sep 7 19:27:14 2009
@@ -0,0 +1,45 @@
+; RUN: opt %s -memcpyopt -disable-output
+; PR4882
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
+target triple = "armv7-eabi"
+
+%struct.qw = type { [4 x float] }
+%struct.bar = type { %struct.qw, %struct.qw, %struct.qw, %struct.qw, %struct.qw, float, float}
+
+define arm_aapcs_vfpcc void @test1(%struct.bar* %this) {
+entry:
+ %0 = getelementptr inbounds %struct.bar* %this, i32 0, i32 0, i32 0, i32 0
+ store float 0.000000e+00, float* %0, align 4
+ %1 = getelementptr inbounds %struct.bar* %this, i32 0, i32 0, i32 0, i32 1
+ store float 0.000000e+00, float* %1, align 4
+ %2 = getelementptr inbounds %struct.bar* %this, i32 0, i32 0, i32 0, i32 2
+ store float 0.000000e+00, float* %2, align 4
+ %3 = getelementptr inbounds %struct.bar* %this, i32 0, i32 0, i32 0, i32 3
+ store float 0.000000e+00, float* %3, align 4
+ %4 = getelementptr inbounds %struct.bar* %this, i32 0, i32 1, i32 0, i32 0
+ store float 0.000000e+00, float* %4, align 4
+ %5 = getelementptr inbounds %struct.bar* %this, i32 0, i32 1, i32 0, i32 1
+ store float 0.000000e+00, float* %5, align 4
+ %6 = getelementptr inbounds %struct.bar* %this, i32 0, i32 1, i32 0, i32 2
+ store float 0.000000e+00, float* %6, align 4
+ %7 = getelementptr inbounds %struct.bar* %this, i32 0, i32 1, i32 0, i32 3
+ store float 0.000000e+00, float* %7, align 4
+ %8 = getelementptr inbounds %struct.bar* %this, i32 0, i32 3, i32 0, i32 1
+ store float 0.000000e+00, float* %8, align 4
+ %9 = getelementptr inbounds %struct.bar* %this, i32 0, i32 3, i32 0, i32 2
+ store float 0.000000e+00, float* %9, align 4
+ %10 = getelementptr inbounds %struct.bar* %this, i32 0, i32 3, i32 0, i32 3
+ store float 0.000000e+00, float* %10, align 4
+ %11 = getelementptr inbounds %struct.bar* %this, i32 0, i32 4, i32 0, i32 0
+ store float 0.000000e+00, float* %11, align 4
+ %12 = getelementptr inbounds %struct.bar* %this, i32 0, i32 4, i32 0, i32 1
+ store float 0.000000e+00, float* %12, align 4
+ %13 = getelementptr inbounds %struct.bar* %this, i32 0, i32 4, i32 0, i32 2
+ store float 0.000000e+00, float* %13, align 4
+ %14 = getelementptr inbounds %struct.bar* %this, i32 0, i32 4, i32 0, i32 3
+ store float 0.000000e+00, float* %14, align 4
+ %15 = getelementptr inbounds %struct.bar* %this, i32 0, i32 5
+ store float 0.000000e+00, float* %15, align 4
+ unreachable
+}
From sabre at nondot.org Mon Sep 7 20:22:54 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 01:22:54 -0000
Subject: [llvm-commits] [llvm] r81177 -
/llvm/trunk/include/llvm/Analysis/Dominators.h
Message-ID: <200909080122.n881MsCR032555@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 20:22:54 2009
New Revision: 81177
URL: http://llvm.org/viewvc/llvm-project?rev=81177&view=rev
Log:
fix PR4915, a crash in -debug mode.
Modified:
llvm/trunk/include/llvm/Analysis/Dominators.h
Modified: llvm/trunk/include/llvm/Analysis/Dominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=81177&r1=81176&r2=81177&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/Dominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/Dominators.h Mon Sep 7 20:22:54 2009
@@ -548,7 +548,9 @@
o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
o << "\n";
- PrintDomTree(getRootNode(), o, 1);
+ // The postdom tree can have a null root if there are no returns.
+ if (getRootNode())
+ PrintDomTree(getRootNode(), o, 1);
}
protected:
From nicholas at mxc.ca Mon Sep 7 20:23:52 2009
From: nicholas at mxc.ca (Nick Lewycky)
Date: Tue, 08 Sep 2009 01:23:52 -0000
Subject: [llvm-commits] [llvm] r81179 - /llvm/trunk/lib/VMCore/Verifier.cpp
Message-ID: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
Author: nicholas
Date: Mon Sep 7 20:23:52 2009
New Revision: 81179
URL: http://llvm.org/viewvc/llvm-project?rev=81179&view=rev
Log:
Verify types. Invalid types can be constructed when assertions are off.
Make the verifier more robust by avoiding unprotected cast<> calls. Notably,
Assert1(isa<>); cast<> is not safe as Assert1 does not terminate the program.
Modified:
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=81179&r1=81178&r2=81179&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Sep 7 20:23:52 2009
@@ -50,12 +50,14 @@
#include "llvm/ModuleProvider.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
+#include "llvm/TypeSymbolTable.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -105,8 +107,7 @@
static const PassInfo *const PreVerifyID = &PreVer;
namespace {
- struct VISIBILITY_HIDDEN
- Verifier : public FunctionPass, public InstVisitor {
+ struct Verifier : public FunctionPass, public InstVisitor {
static char ID; // Pass ID, replacement for typeid
bool Broken; // Is this module found to be broken?
bool RealPass; // Are we not being run by a PassManager?
@@ -124,6 +125,9 @@
/// an instruction in the same block.
SmallPtrSet InstsInThisBlock;
+ /// CheckedTypes - keep track of the types that have been checked already.
+ SmallSet CheckedTypes;
+
Verifier()
: FunctionPass(&ID),
Broken(false), RealPass(true), action(AbortProcessAction),
@@ -282,6 +286,7 @@
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs,
const Value *V);
+ void VerifyType(const Type *Ty);
void WriteValue(const Value *V) {
if (!V) return;
@@ -322,6 +327,15 @@
WriteValue(V3);
Broken = true;
}
+
+ void CheckFailed(const Twine &Message, const Type* T1,
+ const Type* T2 = 0, const Type* T3 = 0) {
+ MessagesStr << Message.str() << "\n";
+ WriteType(T1);
+ WriteType(T2);
+ WriteType(T3);
+ Broken = true;
+ }
};
} // End anonymous namespace
@@ -360,14 +374,14 @@
Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(),
"Global is marked as dllimport, but not external", &GV);
-
+
Assert1(!GV.hasAppendingLinkage() || isa(GV),
"Only global variables can have appending linkage!", &GV);
if (GV.hasAppendingLinkage()) {
- GlobalVariable &GVar = cast(GV);
- Assert1(isa(GVar.getType()->getElementType()),
- "Only global arrays can have appending linkage!", &GV);
+ GlobalVariable *GVar = dyn_cast(&GV);
+ Assert1(GVar && isa(GVar->getType()->getElementType()),
+ "Only global arrays can have appending linkage!", GVar);
}
}
@@ -445,6 +459,8 @@
}
void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) {
+ for (TypeSymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I)
+ VerifyType(I->second);
}
// VerifyParameterAttrs - Check the given attributes for an argument or return
@@ -987,11 +1003,14 @@
"PHI nodes not grouped at top of basic block!",
&PN, PN.getParent());
- // Check that all of the operands of the PHI node have the same type as the
- // result.
- for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
+ // Check that all of the values of the PHI node have the same type as the
+ // result, and that the incoming blocks are really basic blocks.
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
Assert1(PN.getType() == PN.getIncomingValue(i)->getType(),
"PHI node operands are not the same type as the result!", &PN);
+ Assert1(PN.getOperand(PHINode::getOperandNumForIncomingBlock(i)),
+ "PHI node incoming block is not a BasicBlock!", &PN);
+ }
// All other PHI node constraints are checked in the visitBasicBlock method.
@@ -1001,13 +1020,20 @@
void Verifier::VerifyCallSite(CallSite CS) {
Instruction *I = CS.getInstruction();
- Assert1(isa(CS.getCalledValue()->getType()),
- "Called function must be a pointer!", I);
- const PointerType *FPTy = cast(CS.getCalledValue()->getType());
- Assert1(isa(FPTy->getElementType()),
- "Called function is not pointer to function type!", I);
+ const PointerType *FPTy =
+ dyn_cast(CS.getCalledValue()->getType());
+ if (!FPTy) {
+ CheckFailed("Called function must be a pointer!", I);
+ visitInstruction(*I);
+ return;
+ }
- const FunctionType *FTy = cast(FPTy->getElementType());
+ const FunctionType *FTy = dyn_cast(FPTy->getElementType());
+ if (!FTy) {
+ CheckFailed("Called function is not pointer to function type!", I);
+ visitInstruction(*I);
+ return;
+ }
// Verify that the correct number of arguments are being passed
if (FTy->isVarArg())
@@ -1212,22 +1238,29 @@
}
void Verifier::visitLoadInst(LoadInst &LI) {
- const Type *ElTy =
- cast(LI.getOperand(0)->getType())->getElementType();
- Assert2(ElTy == LI.getType(),
- "Load result type does not match pointer operand type!", &LI, ElTy);
- Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
- "Can't load metadata!", &LI);
+ const PointerType *PTy = dyn_cast(LI.getOperand(0)->getType());
+ Assert1(PTy, "Load operand must be a pointer.", &LI);
+ if (PTy) {
+ const Type *ElTy = PTy->getElementType();
+ Assert2(ElTy == LI.getType(),
+ "Load result type does not match pointer operand type!", &LI, ElTy);
+ Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
+ "Can't load metadata!", &LI);
+ }
visitInstruction(LI);
}
void Verifier::visitStoreInst(StoreInst &SI) {
- const Type *ElTy =
- cast(SI.getOperand(1)->getType())->getElementType();
- Assert2(ElTy == SI.getOperand(0)->getType(),
- "Stored value type does not match pointer operand type!", &SI, ElTy);
- Assert1(ElTy != Type::getMetadataTy(SI.getContext()),
- "Can't store metadata!", &SI);
+ const PointerType *PTy = dyn_cast(SI.getOperand(1)->getType());
+ Assert1(PTy, "Load operand must be a pointer.", &SI);
+ if (PTy) {
+ const Type *ElTy = PTy->getElementType();
+ Assert2(ElTy == SI.getOperand(0)->getType(),
+ "Stored value type does not match pointer operand type!",
+ &SI, ElTy);
+ Assert1(ElTy != Type::getMetadataTy(SI.getContext()),
+ "Can't store metadata!", &SI);
+ }
visitInstruction(SI);
}
@@ -1303,11 +1336,11 @@
// instruction, it is an error!
for (User::use_iterator UI = I.use_begin(), UE = I.use_end();
UI != UE; ++UI) {
- Assert1(isa(*UI), "Use of instruction is not an instruction!",
- *UI);
- Instruction *Used = cast(*UI);
- Assert2(Used->getParent() != 0, "Instruction referencing instruction not"
- " embedded in a basic block!", &I, Used);
+ if (Instruction *Used = dyn_cast(*UI))
+ Assert2(Used->getParent() != 0, "Instruction referencing instruction not"
+ " embedded in a basic block!", &I, Used);
+ else
+ CheckFailed("Use of instruction is not an instruction!", *UI);
}
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
@@ -1357,7 +1390,9 @@
// value in the predecessor basic blocks they correspond to.
BasicBlock *UseBlock = BB;
if (isa(I))
- UseBlock = cast(I.getOperand(i+1));
+ UseBlock = dyn_cast(I.getOperand(i+1));
+ // Avoid crash. The verifier will find this module broken anyways.
+ if (!UseBlock) UseBlock = BB;
if (isa(I) && UseBlock == OpBlock) {
// Special case of a phi node in the normal destination or the unwind
@@ -1390,9 +1425,9 @@
} else if (isa(I)) {
// PHI nodes are more difficult than other nodes because they actually
// "use" the value in the predecessor basic blocks they correspond to.
- BasicBlock *PredBB = cast(I.getOperand(i+1));
- Assert2(DT->dominates(OpBlock, PredBB) ||
- !DT->isReachableFromEntry(PredBB),
+ BasicBlock *PredBB = dyn_cast(I.getOperand(i+1));
+ Assert2(PredBB && (DT->dominates(OpBlock, PredBB) ||
+ !DT->isReachableFromEntry(PredBB)),
"Instruction does not dominate all uses!", Op, &I);
} else {
if (OpBlock == BB) {
@@ -1413,6 +1448,67 @@
}
}
InstsInThisBlock.insert(&I);
+
+ VerifyType(I.getType());
+}
+
+/// VerifyType - Verify that a type is well formed.
+///
+void Verifier::VerifyType(const Type *Ty) {
+ // We insert complex types into CheckedTypes even if they failed verification
+ // to prevent emitting messages about them multiple times if
+
+ switch (Ty->getTypeID()) {
+ case Type::FunctionTyID: {
+ if (!CheckedTypes.insert(Ty)) return;
+ const FunctionType *FTy = cast(Ty);
+
+ const Type *RetTy = FTy->getReturnType();
+ Assert2(FunctionType::isValidReturnType(RetTy),
+ "Function type with invalid return type", RetTy, FTy);
+ VerifyType(RetTy);
+
+ for (int i = 0, e = FTy->getNumParams(); i != e; ++i) {
+ const Type *ElTy = FTy->getParamType(i);
+ Assert2(FunctionType::isValidArgumentType(ElTy),
+ "Function type with invalid parameter type", ElTy, FTy);
+ VerifyType(ElTy);
+ }
+ } break;
+ case Type::StructTyID: {
+ if (!CheckedTypes.insert(Ty)) return;
+ const StructType *STy = cast(Ty);
+ for (int i = 0, e = STy->getNumElements(); i != e; ++i) {
+ const Type *ElTy = STy->getElementType(i);
+ Assert2(StructType::isValidElementType(ElTy),
+ "Structure type with invalid element type", ElTy, STy);
+ VerifyType(ElTy);
+ }
+ } break;
+ case Type::ArrayTyID: {
+ if (!CheckedTypes.insert(Ty)) return;
+ const ArrayType *ATy = cast(Ty);
+ Assert1(ArrayType::isValidElementType(ATy->getElementType()),
+ "Array type with invalid element type", ATy);
+ VerifyType(ATy->getElementType());
+ } break;
+ case Type::PointerTyID: {
+ if (!CheckedTypes.insert(Ty)) return;
+ const PointerType *PTy = cast(Ty);
+ Assert1(PointerType::isValidElementType(PTy->getElementType()),
+ "Pointer type with invalid element type", PTy);
+ VerifyType(PTy->getElementType());
+ }
+ case Type::VectorTyID: {
+ if (!CheckedTypes.insert(Ty)) return;
+ const VectorType *VTy = cast(Ty);
+ Assert1(VectorType::isValidElementType(VTy->getElementType()),
+ "Vector type with invalid element type", VTy);
+ VerifyType(VTy->getElementType());
+ }
+ default:
+ return;
+ }
}
// Flags used by TableGen to mark intrinsic parameters with the
From evan.cheng at apple.com Mon Sep 7 20:43:22 2009
From: evan.cheng at apple.com (Evan Cheng)
Date: Mon, 7 Sep 2009 18:43:22 -0700
Subject: [llvm-commits] [PATCH] Add malloc call utility functions
In-Reply-To:
References: <1B994CDD-5E0A-4255-8B22-1781A229B2BB@apple.com>
Message-ID: <7C34C391-C3B0-4677-BF43-717A17CBDD63@apple.com>
Hi Victor,
Some comments:
+// This family of functions help identify calls to malloc.
This comment isn't accurate, right? Please update. Thanks.
+const CallInst* IsMallocCall(const Value* I);
+const PointerType* GetMallocType(const CallInst* CI);
I don't have a strong opinion about this. But our naming convention
seems to be lower case 'is' and 'get'. See Constants.h.
+CallInst* IsMallocCall(Value* I);
This is not a very good name for what is does. Perhaps ExtractMallocCall
IsMallocBitCast
Perhaps isBitCastOfMallocCall?
+ // Determine type only if there is only 1 bitcast use of CI
Period at the end please. :-)
+#if 1
return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), 0, Name));
+#else
Please don't leave #if #else around.
Thanks,
Evan
On Sep 4, 2009, at 5:58 PM, Victor Hernandez wrote:
> Here is an update to this patch to incorporate suggested changes.
>
> I also went ahead and started modifying the optimization passes and
> transforms to use the MallocHelper functions, so that I know I have
> the right helper functions. The changes to the passes are not in
> this patch, but will be coming next.
>
> Also I have included the LLParser, BitCodeReader, and VMCore changes
> that use the new malloc codegen instead of MallocInst. Those
> changes are disabled by default until the changes to the passes are
> in.
>
>
>
> Victor
>
>> I am working on fixing the MallocInst/i64 alloca bug:
>> http://llvm.org/bugs/show_bug.cgi?id=715
>>
>> Here is the first of a series of patches that will result in
>> tearing out MallocInst. Before I can tear it out, I need to update
>> all of the optimization passes and transforms that operate on
>> MallocInst to operate on malloc CallInst instead.
>>
>> This patch consists of a set of utility functions that create IR
>> for malloc calls and identify that IR. It also rewrites
>> LowerAllocations to use the new utility function,
>> CallInst::CreateMalloc().
>>
>>
>>
>> Victor
>>
>> ---
>> Victor Hernandez vhernandez at apple.com
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
From clattner at apple.com Mon Sep 7 20:43:24 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 18:43:24 -0700
Subject: [llvm-commits] [llvm] r81179 -
/llvm/trunk/lib/VMCore/Verifier.cpp
In-Reply-To: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
References: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
Message-ID:
On Sep 7, 2009, at 6:23 PM, Nick Lewycky wrote:
> Author: nicholas
> Date: Mon Sep 7 20:23:52 2009
> New Revision: 81179
>
> URL: http://llvm.org/viewvc/llvm-project?rev=81179&view=rev
> Log:
> Verify types. Invalid types can be constructed when assertions are
> off.
>
> Make the verifier more robust by avoiding unprotected cast<> calls.
> Notably,
> Assert1(isa<>); cast<> is not safe as Assert1 does not terminate the
> program.
Please add "isValidElementType" to LangRef type classifications and
clarify the operation constraints as appropriate.
> + void CheckFailed(const Twine &Message, const Type* T1,
> + const Type* T2 = 0, const Type* T3 = 0) {
Please don't put the *'s in the wrong place.
> - // Check that all of the operands of the PHI node have the same
> type as the
> - // result.
> - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
> + // Check that all of the values of the PHI node have the same
> type as the
> + // result, and that the incoming blocks are really basic blocks.
> + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
> Assert1(PN.getType() == PN.getIncomingValue(i)->getType(),
> "PHI node operands are not the same type as the
> result!", &PN);
> + Assert1(PN.getOperand(PHINode::getOperandNumForIncomingBlock(i)),
> + "PHI node incoming block is not a BasicBlock!", &PN);
How is this checking that the operand is a basic block? At the least,
this should have a comment.
> void Verifier::visitLoadInst(LoadInst &LI) {
> - const Type *ElTy =
> - cast(LI.getOperand(0)->getType())->getElementType();
> - Assert2(ElTy == LI.getType(),
> - "Load result type does not match pointer operand type!",
> &LI, ElTy);
> - Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
> - "Can't load metadata!", &LI);
> + const PointerType *PTy = dyn_cast(LI.getOperand(0)-
> >getType());
> + Assert1(PTy, "Load operand must be a pointer.", &LI);
> + if (PTy) {
> + const Type *ElTy = PTy->getElementType();
> + Assert2(ElTy == LI.getType(),
> + "Load result type does not match pointer operand
> type!", &LI, ElTy);
> + Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
> + "Can't load metadata!", &LI);
> + }
This isn't needed. Assert1 does a "return" on error, many of the
other changes aren't needed either.
> +void Verifier::VerifyType(const Type *Ty) {
> + // We insert complex types into CheckedTypes even if they failed
> verification
> + // to prevent emitting messages about them multiple times if
Half formed thought.
> +
> + switch (Ty->getTypeID()) {
> + case Type::FunctionTyID: {
> + if (!CheckedTypes.insert(Ty)) return;
Why don't you do the insert before the switch?
> + const FunctionType *FTy = cast(Ty);
> +
> + const Type *RetTy = FTy->getReturnType();
> + Assert2(FunctionType::isValidReturnType(RetTy),
> + "Function type with invalid return type", RetTy, FTy);
> + VerifyType(RetTy);
> +
> + for (int i = 0, e = FTy->getNumParams(); i != e; ++i) {
Please use 'unsigned i' here and in other places.
Thanks for working on this!
-Chris
From gohman at apple.com Mon Sep 7 20:44:02 2009
From: gohman at apple.com (Dan Gohman)
Date: Tue, 08 Sep 2009 01:44:02 -0000
Subject: [llvm-commits] [llvm] r81180 - in /llvm/trunk:
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
test/CodeGen/X86/store-empty-member.ll
Message-ID: <200909080144.n881i2mp002874@zion.cs.uiuc.edu>
Author: djg
Date: Mon Sep 7 20:44:02 2009
New Revision: 81180
URL: http://llvm.org/viewvc/llvm-project?rev=81180&view=rev
Log:
Fix an abort on a store of an empty struct member. getValue returns
null in the case of an empty struct, so don't try to call getNumValues
on it.
Added:
llvm/trunk/test/CodeGen/X86/store-empty-member.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=81180&r1=81179&r2=81180&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Mon Sep 7 20:44:02 2009
@@ -861,6 +861,10 @@
for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end();
OI != OE; ++OI) {
SDNode *Val = getValue(*OI).getNode();
+ // If the operand is an empty aggregate, there are no values.
+ if (!Val) continue;
+ // Add each leaf value from the operand to the Constants list
+ // to form a flattened list of all the values.
for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i)
Constants.push_back(SDValue(Val, i));
}
Added: llvm/trunk/test/CodeGen/X86/store-empty-member.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/store-empty-member.ll?rev=81180&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/store-empty-member.ll (added)
+++ llvm/trunk/test/CodeGen/X86/store-empty-member.ll Mon Sep 7 20:44:02 2009
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=x86 | FileCheck %s
+
+; Don't crash on an empty struct member.
+
+; CHECK: movl $2, 4(%esp)
+; CHECK: movl $1, (%esp)
+
+%testType = type {i32, [0 x i32], i32}
+
+define void @foo() nounwind {
+ %1 = alloca %testType
+ volatile store %testType {i32 1, [0 x i32] zeroinitializer, i32 2}, %testType* %1
+ ret void
+}
From nicholas at mxc.ca Mon Sep 7 21:02:40 2009
From: nicholas at mxc.ca (Nick Lewycky)
Date: Tue, 08 Sep 2009 02:02:40 -0000
Subject: [llvm-commits] [llvm] r81182 - /llvm/trunk/lib/VMCore/Verifier.cpp
Message-ID: <200909080202.n8822evs005241@zion.cs.uiuc.edu>
Author: nicholas
Date: Mon Sep 7 21:02:39 2009
New Revision: 81182
URL: http://llvm.org/viewvc/llvm-project?rev=81182&view=rev
Log:
Simplify from my last change. Assert1 is a macro that makes its caller return,
so "Assert1(isa<>); cast<>" is a valid idiom.
Actually check the PHI node's odd-numbered operands for BasicBlock-ness, like
the comment said.
Modified:
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=81182&r1=81181&r2=81182&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Mon Sep 7 21:02:39 2009
@@ -319,8 +319,8 @@
Broken = true;
}
- void CheckFailed(const Twine &Message, const Value* V1,
- const Type* T2, const Value* V3 = 0) {
+ void CheckFailed(const Twine &Message, const Value *V1,
+ const Type *T2, const Value *V3 = 0) {
MessagesStr << Message.str() << "\n";
WriteValue(V1);
WriteType(T2);
@@ -328,8 +328,8 @@
Broken = true;
}
- void CheckFailed(const Twine &Message, const Type* T1,
- const Type* T2 = 0, const Type* T3 = 0) {
+ void CheckFailed(const Twine &Message, const Type *T1,
+ const Type *T2 = 0, const Type *T3 = 0) {
MessagesStr << Message.str() << "\n";
WriteType(T1);
WriteType(T2);
@@ -1008,7 +1008,8 @@
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
Assert1(PN.getType() == PN.getIncomingValue(i)->getType(),
"PHI node operands are not the same type as the result!", &PN);
- Assert1(PN.getOperand(PHINode::getOperandNumForIncomingBlock(i)),
+ Assert1(isa(PN.getOperand(
+ PHINode::getOperandNumForIncomingBlock(i))),
"PHI node incoming block is not a BasicBlock!", &PN);
}
@@ -1020,20 +1021,13 @@
void Verifier::VerifyCallSite(CallSite CS) {
Instruction *I = CS.getInstruction();
- const PointerType *FPTy =
- dyn_cast(CS.getCalledValue()->getType());
- if (!FPTy) {
- CheckFailed("Called function must be a pointer!", I);
- visitInstruction(*I);
- return;
- }
-
- const FunctionType *FTy = dyn_cast(FPTy->getElementType());
- if (!FTy) {
- CheckFailed("Called function is not pointer to function type!", I);
- visitInstruction(*I);
- return;
- }
+ Assert1(isa(CS.getCalledValue()->getType()),
+ "Called function must be a pointer!", I);
+ const PointerType *FPTy = cast(CS.getCalledValue()->getType());
+
+ Assert1(isa(FPTy->getElementType()),
+ "Called function is not pointer to function type!", I);
+ const FunctionType *FTy = cast(FPTy->getElementType());
// Verify that the correct number of arguments are being passed
if (FTy->isVarArg())
@@ -1240,27 +1234,23 @@
void Verifier::visitLoadInst(LoadInst &LI) {
const PointerType *PTy = dyn_cast(LI.getOperand(0)->getType());
Assert1(PTy, "Load operand must be a pointer.", &LI);
- if (PTy) {
- const Type *ElTy = PTy->getElementType();
- Assert2(ElTy == LI.getType(),
- "Load result type does not match pointer operand type!", &LI, ElTy);
- Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
- "Can't load metadata!", &LI);
- }
+ const Type *ElTy = PTy->getElementType();
+ Assert2(ElTy == LI.getType(),
+ "Load result type does not match pointer operand type!", &LI, ElTy);
+ Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
+ "Can't load metadata!", &LI);
visitInstruction(LI);
}
void Verifier::visitStoreInst(StoreInst &SI) {
const PointerType *PTy = dyn_cast(SI.getOperand(1)->getType());
Assert1(PTy, "Load operand must be a pointer.", &SI);
- if (PTy) {
- const Type *ElTy = PTy->getElementType();
- Assert2(ElTy == SI.getOperand(0)->getType(),
- "Stored value type does not match pointer operand type!",
- &SI, ElTy);
- Assert1(ElTy != Type::getMetadataTy(SI.getContext()),
- "Can't store metadata!", &SI);
- }
+ const Type *ElTy = PTy->getElementType();
+ Assert2(ElTy == SI.getOperand(0)->getType(),
+ "Stored value type does not match pointer operand type!",
+ &SI, ElTy);
+ Assert1(ElTy != Type::getMetadataTy(SI.getContext()),
+ "Can't store metadata!", &SI);
visitInstruction(SI);
}
@@ -1339,8 +1329,10 @@
if (Instruction *Used = dyn_cast(*UI))
Assert2(Used->getParent() != 0, "Instruction referencing instruction not"
" embedded in a basic block!", &I, Used);
- else
+ else {
CheckFailed("Use of instruction is not an instruction!", *UI);
+ return;
+ }
}
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
@@ -1391,8 +1383,8 @@
BasicBlock *UseBlock = BB;
if (isa(I))
UseBlock = dyn_cast(I.getOperand(i+1));
- // Avoid crash. The verifier will find this module broken anyways.
- if (!UseBlock) UseBlock = BB;
+ Assert2(UseBlock, "Invoke operand is PHI node with bad incoming-BB",
+ Op, &I);
if (isa(I) && UseBlock == OpBlock) {
// Special case of a phi node in the normal destination or the unwind
@@ -1468,7 +1460,7 @@
"Function type with invalid return type", RetTy, FTy);
VerifyType(RetTy);
- for (int i = 0, e = FTy->getNumParams(); i != e; ++i) {
+ for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
const Type *ElTy = FTy->getParamType(i);
Assert2(FunctionType::isValidArgumentType(ElTy),
"Function type with invalid parameter type", ElTy, FTy);
@@ -1478,7 +1470,7 @@
case Type::StructTyID: {
if (!CheckedTypes.insert(Ty)) return;
const StructType *STy = cast(Ty);
- for (int i = 0, e = STy->getNumElements(); i != e; ++i) {
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
const Type *ElTy = STy->getElementType(i);
Assert2(StructType::isValidElementType(ElTy),
"Structure type with invalid element type", ElTy, STy);
From nicholas at mxc.ca Mon Sep 7 21:02:58 2009
From: nicholas at mxc.ca (Nick Lewycky)
Date: Mon, 07 Sep 2009 19:02:58 -0700
Subject: [llvm-commits] [llvm] r81179 -
/llvm/trunk/lib/VMCore/Verifier.cpp
In-Reply-To:
References: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
Message-ID: <4AA5BB52.1060002@mxc.ca>
Chris Lattner wrote:
>
> On Sep 7, 2009, at 6:23 PM, Nick Lewycky wrote:
>
>> Author: nicholas
>> Date: Mon Sep 7 20:23:52 2009
>> New Revision: 81179
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=81179&view=rev
>> Log:
>> Verify types. Invalid types can be constructed when assertions are off.
>>
>> Make the verifier more robust by avoiding unprotected cast<> calls.
>> Notably,
>> Assert1(isa<>); cast<> is not safe as Assert1 does not terminate the
>> program.
>
> Please add "isValidElementType" to LangRef type classifications and
> clarify the operation constraints as appropriate.
Okay, I'll do that later, but soon. This patch isn't changing the
language, but you're right that the LangRef isn't being as clear as it
should.
>> + void CheckFailed(const Twine &Message, const Type* T1,
>> + const Type* T2 = 0, const Type* T3 = 0) {
>
> Please don't put the *'s in the wrong place.
Fixed, and fixed where I copied it from.
>> - // Check that all of the operands of the PHI node have the same
>> type as the
>> - // result.
>> - for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
>> + // Check that all of the values of the PHI node have the same type
>> as the
>> + // result, and that the incoming blocks are really basic blocks.
>> + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
>> Assert1(PN.getType() == PN.getIncomingValue(i)->getType(),
>> "PHI node operands are not the same type as the result!",
>> &PN);
>> + Assert1(PN.getOperand(PHINode::getOperandNumForIncomingBlock(i)),
>> + "PHI node incoming block is not a BasicBlock!", &PN);
>
> How is this checking that the operand is a basic block? At the least,
> this should have a comment.
Whoa, missing isa!
>> void Verifier::visitLoadInst(LoadInst &LI) {
>> - const Type *ElTy =
>> - cast(LI.getOperand(0)->getType())->getElementType();
>> - Assert2(ElTy == LI.getType(),
>> - "Load result type does not match pointer operand type!",
>> &LI, ElTy);
>> - Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
>> - "Can't load metadata!", &LI);
>> + const PointerType *PTy =
>> dyn_cast(LI.getOperand(0)->getType());
>> + Assert1(PTy, "Load operand must be a pointer.", &LI);
>> + if (PTy) {
>> + const Type *ElTy = PTy->getElementType();
>> + Assert2(ElTy == LI.getType(),
>> + "Load result type does not match pointer operand type!",
>> &LI, ElTy);
>> + Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
>> + "Can't load metadata!", &LI);
>> + }
>
> This isn't needed. Assert1 does a "return" on error, many of the other
> changes aren't needed either.
Thanks for pointing this out. I've reverted the needless changes.
>> +void Verifier::VerifyType(const Type *Ty) {
>> + // We insert complex types into CheckedTypes even if they failed
>> verification
>> + // to prevent emitting messages about them multiple times if
>
> Half formed thought.
Fixed.
>> +
>> + switch (Ty->getTypeID()) {
>> + case Type::FunctionTyID: {
>> + if (!CheckedTypes.insert(Ty)) return;
>
> Why don't you do the insert before the switch?
Because I don't want to insert the integers, double, labels, etc. They
all go through the default case.
>> + const FunctionType *FTy = cast(Ty);
>> +
>> + const Type *RetTy = FTy->getReturnType();
>> + Assert2(FunctionType::isValidReturnType(RetTy),
>> + "Function type with invalid return type", RetTy, FTy);
>> + VerifyType(RetTy);
>> +
>> + for (int i = 0, e = FTy->getNumParams(); i != e; ++i) {
>
> Please use 'unsigned i' here and in other places.
Fixed.
Thanks for the review!
Nick
From sabre at nondot.org Mon Sep 7 22:32:54 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 03:32:54 -0000
Subject: [llvm-commits] [llvm] r81183 -
/llvm/trunk/include/llvm/Instructions.h
Message-ID: <200909080332.n883Wt11016396@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 22:32:53 2009
New Revision: 81183
URL: http://llvm.org/viewvc/llvm-project?rev=81183&view=rev
Log:
add getVectorOperand/getIndexOperand accessors to ExtractElementInst.
Fix some const correctness problems in SelectInst.
Modified:
llvm/trunk/include/llvm/Instructions.h
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=81183&r1=81182&r2=81183&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Mon Sep 7 22:32:53 2009
@@ -1217,10 +1217,13 @@
return new(3) SelectInst(C, S1, S2, NameStr, InsertAtEnd);
}
- Value *getCondition() const { return Op<0>(); }
- Value *getTrueValue() const { return Op<1>(); }
- Value *getFalseValue() const { return Op<2>(); }
-
+ const Value *getCondition() const { return Op<0>(); }
+ const Value *getTrueValue() const { return Op<1>(); }
+ const Value *getFalseValue() const { return Op<2>(); }
+ Value *getCondition() { return Op<0>(); }
+ Value *getTrueValue() { return Op<1>(); }
+ Value *getFalseValue() { return Op<2>(); }
+
/// areInvalidOperands - Return a string if the specified operands are invalid
/// for a select operation, otherwise return null.
static const char *areInvalidOperands(Value *Cond, Value *True, Value *False);
@@ -1312,6 +1315,16 @@
virtual ExtractElementInst *clone(LLVMContext &Context) const;
+ Value *getVectorOperand() { return Op<0>(); }
+ Value *getIndexOperand() { return Op<1>(); }
+ const Value *getVectorOperand() const { return Op<0>(); }
+ const Value *getIndexOperand() const { return Op<1>(); }
+
+ const VectorType *getVectorOperandType() const {
+ return reinterpret_cast(Instruction::getType());
+ }
+
+
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
From sabre at nondot.org Mon Sep 7 22:39:55 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 03:39:55 -0000
Subject: [llvm-commits] [llvm] r81184 -
/llvm/trunk/include/llvm/Instructions.h
Message-ID: <200909080339.n883dtQf017231@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 22:39:55 2009
New Revision: 81184
URL: http://llvm.org/viewvc/llvm-project?rev=81184&view=rev
Log:
fix pasto
Modified:
llvm/trunk/include/llvm/Instructions.h
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=81184&r1=81183&r2=81184&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Mon Sep 7 22:39:55 2009
@@ -1321,7 +1321,7 @@
const Value *getIndexOperand() const { return Op<1>(); }
const VectorType *getVectorOperandType() const {
- return reinterpret_cast(Instruction::getType());
+ return reinterpret_cast(getVectorOperand()->getType());
}
From ssen at apple.com Mon Sep 7 22:42:07 2009
From: ssen at apple.com (Shantonu Sen)
Date: Mon, 7 Sep 2009 20:42:07 -0700
Subject: [llvm-commits] [PATCH] Remove obsolete autoconf stuff,
and upgrade autoconf, cuts down configure size to 361K (from 1.1M!)
In-Reply-To: <4AA56617.7000108@gmail.com>
References: <4AA26CD9.10007@gmail.com>
<6a8523d60909061449u5ce9b254t9a6398e5e313f4ee@mail.gmail.com>
<70A73AA7-DF18-44A6-B773-AC05DDDEEB6D@apple.com>
<4AA56617.7000108@gmail.com>
Message-ID: <2491B621-2AF7-4171-8DAE-5EE76C3F4F95@apple.com>
On Sep 7, 2009, at 12:59 PM, T?r?k Edwin wrote:
> On 2009-09-07 21:46, Shantonu Sen wrote:
>> This patch looks scary to me. Do we really want to invest in moving
>> to
>> a new autoconf/libtool/automake version that I'm told has known
>> incompatibilities (which means it's unlikely to be used by anyone
>> else)?
>
> I can't regenerate llvm's configure with autoconf 2.61 or autoconf
> 2.64
> which are the only ones available on Debian.
> The regeneration succeeds, but there is a syntax error in configure
> when
> run (a libtool macro is not expanded).
> I'd like to support both autoconf 2.60 and 2.64.
It's trivial to use whatever version of auto* AutoRegen.sh requires:
[ssen at virgon]$ eval `grep ^want_ AutoRegen.sh | grep -v _clean | tr -d
'\'`
[ssen at virgon]$ ( mkdir -p src; cd src; for p in autoconf-$
{want_autoconf_version} automake-${want_aclocal_version} libtool-$
{want_libtool_version}; do curl -O ftp://ftp.gnu.org/pub/gnu/`echo $p
| awk -F- '{print $1}'`/$p.tar.gz; tar zxf $p.tar.gz; cd $p; ./
configure --prefix=$PWD/../../dst && make && make install; cd ..;
done; cd ..; echo "Now add $PWD/dst/bin to the front of your PATH" )
...
Now add /Volumes/HD/ltmp/ssen/llvm/autoconf/dst/bin to the front of
your PATH
[ssen at virgon]$ export PATH=/Volumes/HD/ltmp/ssen/llvm/autoconf/dst/bin:
$PATH
[ssen at virgon]$ ./AutoRegen.sh
...
Every Linux distribution, Mac OS X install, FreeBSD, etc., has a
different combination of auto*/libtool versions. LLVM has standardized
on some versions of those tools, and developers should match.
I don't think AutoRegen.sh should support ranges of tools, because it
makes incremental changes to ./configure meaningless because every
line will change. If it's autoconf-2.64, I think that should be what
AutoRegen.sh requires, even if configure.ac accepts a lower version
for local quick-fix development.
I'm confused about libtool requirements. When I try reconfiguring with
AutoRegen.sh, the resulting ./configure script has:
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
../configure: line 5741: LT_PATH_NM: command not found
checking for GNU make... make
checking whether ln -s works... yes
So is libtool required? If it is, please restore it's requirements to
AutoRegen.sh, even if ltmain.sh is not used at build time.
> Thanks for the review, comments below and new patch attached.
>
>>
>> Some specific issues:
>> 1)
>>> dnl Indicate that we require autoconf 2.59 or later. Ths is needed
>>> because we
>>> dnl use some autoconf macros only available in 2.59.
>>> -AC_PREREQ(2.59)
>>> +AC_PREREQ(2.64)
>>
>> Please update the comments
>
> Sorry that should be AC_PREREQ(2.60), it should still work with
> autoconf
> 2.60.
> I changed AutoRegen.sh to accept both. If you have autoconf 2.60 can
> you
> try whether ./AutoRegen.sh works for you with my patch applied?
>
>>
>> 2)
>>> -want_libtool_version='1\.5\.22'
>>
>> What version of libtool is being used? I can't figure it out. Where
>> is
>> it documented?
>
> In the newly attached I kept libtool at what LLVM currently has, only
> one macro is used from it though, see below: AC_PROG_NM.
> As such I don't think libtool needs to be upgraded.
>
>>
>> 3)
>>> 3. Copy /ltdl.m4 to llvm/autoconf/m4
>>> + 3. Copy /ltsugar.m4 to llvm/autoconf/m4
>>> 4. Copy /share/aclocal/libtool.m4 to llvm/autoconf/m4/
>>> libtool.m4
>>
>> You didn't update any of the step numbering, leading to many
>> duplicate
>> numbered steps and gaps of steps.
>
> Dropped this section from README now, libtool doesn't need to be
> updated
> since we don't use libtool per se.
>
>>
>> 4) I thought the policy was not to upgrade config.guess? Even if not,
>> you've lost several local LLVM changes:
>>> *:Darwin:*:*)
>>> UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
>>> case $UNAME_PROCESSOR in
>>> - *86) UNAME_PROCESSOR=i686 ;;
>>> unknown) UNAME_PROCESSOR=powerpc ;;
>>> esac
>>
>> I don't know what else was overwritten, but it can't be good.
>
> Didn't know it had LLVM local changes, I'll remove the config.*
> updates
> from my patch, and keep them as is.
>
>>
>> 6) These changes use libtool internal macros, like
>> "_LT_PROG_ECHO_BACKSLASH". These are not stable, and should not be
>> used by configure scripts.
>>
>> I think this requirements more refinement.
>
> Yeah that is hackish, I've done it like that to cut down configure
> size.
> However libtool is currently only used to detect the extension of
> shared
> libraries, and for AC_PROG_NM.
> Detecting the shared lib extension with libtool needs LT_INIT that
> adds
> another 300K bloat to configure, instead my latest patch determines
> the shared lib extension with a much simpler m4 macro I copied from
> LLVM's libtool.m4.
>
> I think the libtool.m4 in LLVM allows that, it only has this
> copyright:
>
> ## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
> ## Free Software Foundation, Inc.
> ## Originally by Gordon Matzigkeit , 1996
> ##
> ## This file is free software; the Free Software Foundation gives
> ## unlimited permission to copy and/or distribute it, with or without
> ## modifications, as long as this notice is preserved.
>
> full.patch.gz:
> autoconf/depcomp | 522
> autoconf/ltmain.sh | 6863 -------
> autoconf/m4/bison.m4 | 15
> autoconf/m4/cxx_bidi_iterator.m4 | 22
> autoconf/m4/cxx_fwd_iterator.m4 | 22
> autoconf/m4/cxx_namespaces.m4 | 19
> autoconf/m4/cxx_std_iterator.m4 | 26
> autoconf/m4/flex.m4 | 17
> autoconf/m4/ltdl.m4 | 418
> autoconf/missing | 353
> b/autoconf/AutoRegen.sh | 10
> b/autoconf/README.TXT | 35
> b/autoconf/configure.ac | 40
> b/autoconf/install-sh | 530
> b/autoconf/m4/path_tclsh.m4 | 4
> b/autoconf/m4/shrext.m4 | 38
> b/autoconf/mkinstalldirs | 40
> b/configure |32893
> ++++----------------------------------
> b/include/llvm/Config/config.h.in | 168
> 19 files changed, 4522 insertions(+), 37513 deletions(-)
>
>
> Best regards,
> --Edwin
> <0001-Update-configure.ac-to-work-with-autoconf-2.64.patch><0003-
> Update-install-sh-and-mkinstalldirs.patch><0002-Remove-obsolete-m4-
> macros-and-unused-programs.-Also-.patch.gz><0004-Regenerate-
> configure-and-config.h.in.patch.gz>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20090907/b771ffbf/attachment.html
From sabre at nondot.org Mon Sep 7 22:44:52 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 03:44:52 -0000
Subject: [llvm-commits] [llvm] r81185 - in /llvm/trunk:
lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/crash.ll
Message-ID: <200909080344.n883iq2w017852@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 22:44:51 2009
New Revision: 81185
URL: http://llvm.org/viewvc/llvm-project?rev=81185&view=rev
Log:
instcombine transforms vector loads that are only used by
extractelement operations into a bitcast of the pointer,
then a gep, then a scalar load. Disable this when the vector
only has one element, because it leads to infinite loops in
instcombine (PR4908).
This transformation seems like a really bad idea to me, as it
will likely disable CSE of vector load/stores etc and can be
better done in the code generator when profitable. This
goes all the way back to the first days of packed types,
r25299 specifically.
I'll let those people who care about the performance of vector
code decide what to do with this.
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/crash.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=81185&r1=81184&r2=81185&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 7 22:44:51 2009
@@ -12080,7 +12080,7 @@
// that element. When the elements are not identical, we cannot replace yet
// (we do that below, but only when the index is constant).
Constant *op0 = C->getOperand(0);
- for (unsigned i = 1; i < C->getNumOperands(); ++i)
+ for (unsigned i = 1; i != C->getNumOperands(); ++i)
if (C->getOperand(i) != op0) {
op0 = 0;
break;
@@ -12093,8 +12093,7 @@
// find a previously computed scalar that was inserted into the vector.
if (ConstantInt *IdxC = dyn_cast(EI.getOperand(1))) {
unsigned IndexVal = IdxC->getZExtValue();
- unsigned VectorWidth =
- cast(EI.getOperand(0)->getType())->getNumElements();
+ unsigned VectorWidth = EI.getVectorOperandType()->getNumElements();
// If this is extracting an invalid index, turn this into undef, to avoid
// crashing the code below.
@@ -12146,25 +12145,31 @@
return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1);
}
} else if (LoadInst *LI = dyn_cast(I)) {
- unsigned AS = LI->getPointerAddressSpace();
- Value *Ptr = Builder->CreateBitCast(I->getOperand(0),
- PointerType::get(EI.getType(), AS),
- I->getOperand(0)->getName());
- Value *GEP =
- Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1),
- I->getName()+".gep");
-
- LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
-
- // Make sure the Load goes before the load instruction in the source,
- // not wherever the extract happens to be.
- if (Instruction *P = dyn_cast(Ptr))
- P->moveBefore(I);
- if (Instruction *G = dyn_cast(GEP))
- G->moveBefore(I);
- Load->moveBefore(I);
-
- return ReplaceInstUsesWith(EI, Load);
+// r25299
+ // Instead of loading a vector, then doing an extract element out of it,
+ // just bitcast the pointer operand, do a gep, then load the result.
+ // This shrinks the vector load to a scalar load.
+ if (EI.getVectorOperandType()->getNumElements() != 1) {
+ unsigned AS = LI->getPointerAddressSpace();
+ Value *Ptr = Builder->CreateBitCast(I->getOperand(0),
+ PointerType::get(EI.getType(), AS),
+ I->getOperand(0)->getName());
+ Value *GEP =
+ Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1),
+ I->getName()+".gep");
+
+ LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
+
+ // Make sure the Load goes before the load instruction in the source,
+ // not wherever the extract happens to be.
+ if (Instruction *P = dyn_cast(Ptr))
+ P->moveBefore(I);
+ if (Instruction *G = dyn_cast(GEP))
+ G->moveBefore(I);
+ Load->moveBefore(I);
+
+ return ReplaceInstUsesWith(EI, Load);
+ }
}
}
if (InsertElementInst *IE = dyn_cast(I)) {
Modified: llvm/trunk/test/Transforms/InstCombine/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/crash.ll?rev=81185&r1=81184&r2=81185&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/crash.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/crash.ll Mon Sep 7 22:44:51 2009
@@ -31,3 +31,16 @@
ret <2 x i64> %conv3.i44
}
+
+; PR4908
+define void @test2(<1 x i16>* nocapture %b, i32* nocapture %c) nounwind ssp {
+entry:
+ %arrayidx = getelementptr inbounds <1 x i16>* %b, i64 undef ; <<1 x i16>*>
+ %tmp2 = load <1 x i16>* %arrayidx ; <<1 x i16>> [#uses=1]
+ %tmp6 = bitcast <1 x i16> %tmp2 to i16 ; [#uses=1]
+ %tmp7 = zext i16 %tmp6 to i32 ; [#uses=1]
+ %ins = or i32 0, %tmp7 ; [#uses=1]
+ %arrayidx20 = getelementptr inbounds i32* %c, i64 undef ; [#uses=1]
+ store i32 %ins, i32* %arrayidx20
+ ret void
+}
From sabre at nondot.org Mon Sep 7 22:47:42 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 03:47:42 -0000
Subject: [llvm-commits] [llvm] r81186 -
/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
Message-ID: <200909080347.n883lgxm018214@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 22:47:41 2009
New Revision: 81186
URL: http://llvm.org/viewvc/llvm-project?rev=81186&view=rev
Log:
remove a turd
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=81186&r1=81185&r2=81186&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Mon Sep 7 22:47:41 2009
@@ -12145,7 +12145,6 @@
return BinaryOperator::Create(BO->getOpcode(), newEI0, newEI1);
}
} else if (LoadInst *LI = dyn_cast(I)) {
-// r25299
// Instead of loading a vector, then doing an extract element out of it,
// just bitcast the pointer operand, do a gep, then load the result.
// This shrinks the vector load to a scalar load.
From clattner at apple.com Mon Sep 7 22:48:15 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 20:48:15 -0700
Subject: [llvm-commits] [llvm] r81179 -
/llvm/trunk/lib/VMCore/Verifier.cpp
In-Reply-To: <4AA5BB52.1060002@mxc.ca>
References: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
<4AA5BB52.1060002@mxc.ca>
Message-ID: <632CD9C4-4018-4E5B-B30D-864FA299B2FF@apple.com>
On Sep 7, 2009, at 7:02 PM, Nick Lewycky wrote:
>>> +
>>> + switch (Ty->getTypeID()) {
>>> + case Type::FunctionTyID: {
>>> + if (!CheckedTypes.insert(Ty)) return;
>> Why don't you do the insert before the switch?
>
> Because I don't want to insert the integers, double, labels, etc.
> They all go through the default case.
Why not?
-Chris
From nicholas at mxc.ca Mon Sep 7 23:00:41 2009
From: nicholas at mxc.ca (Nick Lewycky)
Date: Mon, 07 Sep 2009 21:00:41 -0700
Subject: [llvm-commits] [llvm] r81179 -
/llvm/trunk/lib/VMCore/Verifier.cpp
In-Reply-To: <632CD9C4-4018-4E5B-B30D-864FA299B2FF@apple.com>
References: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
<4AA5BB52.1060002@mxc.ca>
<632CD9C4-4018-4E5B-B30D-864FA299B2FF@apple.com>
Message-ID: <4AA5D6E9.5080703@mxc.ca>
Chris Lattner wrote:
> On Sep 7, 2009, at 7:02 PM, Nick Lewycky wrote:
>>>> +
>>>> + switch (Ty->getTypeID()) {
>>>> + case Type::FunctionTyID: {
>>>> + if (!CheckedTypes.insert(Ty)) return;
>>> Why don't you do the insert before the switch?
>>
>> Because I don't want to insert the integers, double, labels, etc. They
>> all go through the default case.
>
> Why not?
It's a waste of ram and cycles. We know that those are always valid, we
never need to check them. We certainly don't need to store PATypeHolders
for them in CheckedTypes.
While I wouldn't really mind doing this for non-derived types, what made
my mind up was IntegerType and the fact you could in theory have 100,000
different integer types.
Of course, the way it's written now is a jump-threading testcase. If you
want me to stop arguing and change it, just let me know. :)
Nick
From clattner at apple.com Mon Sep 7 23:20:16 2009
From: clattner at apple.com (Chris Lattner)
Date: Mon, 7 Sep 2009 21:20:16 -0700
Subject: [llvm-commits] [llvm] r81179 -
/llvm/trunk/lib/VMCore/Verifier.cpp
In-Reply-To: <4AA5D6E9.5080703@mxc.ca>
References: <200909080123.n881Nqkv032723@zion.cs.uiuc.edu>
<4AA5BB52.1060002@mxc.ca>
<632CD9C4-4018-4E5B-B30D-864FA299B2FF@apple.com>
<4AA5D6E9.5080703@mxc.ca>
Message-ID: <3014E3F5-8538-4790-8A33-D3D37DE54765@apple.com>
On Sep 7, 2009, at 9:00 PM, Nick Lewycky wrote:
> Chris Lattner wrote:
>> On Sep 7, 2009, at 7:02 PM, Nick Lewycky wrote:
>>>>> +
>>>>> + switch (Ty->getTypeID()) {
>>>>> + case Type::FunctionTyID: {
>>>>> + if (!CheckedTypes.insert(Ty)) return;
>>>> Why don't you do the insert before the switch?
>>>
>>> Because I don't want to insert the integers, double, labels, etc.
>>> They all go through the default case.
>> Why not?
>
> It's a waste of ram and cycles. We know that those are always valid,
> we never need to check them. We certainly don't need to store
> PATypeHolders for them in CheckedTypes.
>
> While I wouldn't really mind doing this for non-derived types, what
> made my mind up was IntegerType and the fact you could in theory
> have 100,000 different integer types.
>
> Of course, the way it's written now is a jump-threading testcase. If
> you want me to stop arguing and change it, just let me know. :)
Please just change it. I'd rather have the verifier be simple and
small than trying to optimize out a dozen insertions.
-chris
From sabre at nondot.org Mon Sep 7 23:55:44 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 04:55:44 -0000
Subject: [llvm-commits] [llvm] r81187 - in /llvm/trunk:
lib/Target/X86/X86FloatingPoint.cpp test/CodeGen/X86/fp-stack-O0-crash.ll
Message-ID: <200909080455.n884tiBM026947@zion.cs.uiuc.edu>
Author: lattner
Date: Mon Sep 7 23:55:44 2009
New Revision: 81187
URL: http://llvm.org/viewvc/llvm-project?rev=81187&view=rev
Log:
fix PR4767, a crash because fp stackifier visited blocks in
depth first order, so it wouldn't process unreachable blocks.
When compiling at -O0, late dead block elimination isn't done
and the bad instructions got to isel.
Added:
llvm/trunk/test/CodeGen/X86/fp-stack-O0-crash.ll
Modified:
llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp
Modified: llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp?rev=81187&r1=81186&r2=81187&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FloatingPoint.cpp Mon Sep 7 23:55:44 2009
@@ -213,6 +213,14 @@
I != E; ++I)
Changed |= processBasicBlock(MF, **I);
+ // Process any unreachable blocks in arbitrary order now.
+ if (MF.size() == Processed.size())
+ return Changed;
+
+ for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
+ if (Processed.insert(BB))
+ Changed |= processBasicBlock(MF, *BB);
+
return Changed;
}
Added: llvm/trunk/test/CodeGen/X86/fp-stack-O0-crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fp-stack-O0-crash.ll?rev=81187&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fp-stack-O0-crash.ll (added)
+++ llvm/trunk/test/CodeGen/X86/fp-stack-O0-crash.ll Mon Sep 7 23:55:44 2009
@@ -0,0 +1,30 @@
+; RUN: llc %s -O0 -fast-isel -regalloc=local -o -
+; PR4767
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin10"
+
+define void @fn(x86_fp80 %x) nounwind ssp {
+entry:
+ %x.addr = alloca x86_fp80 ; [#uses=5]
+ store x86_fp80 %x, x86_fp80* %x.addr
+ br i1 false, label %cond.true, label %cond.false
+
+cond.true: ; preds = %entry
+ %tmp = load x86_fp80* %x.addr ; [#uses=1]
+ %tmp1 = load x86_fp80* %x.addr ; [#uses=1]
+ %cmp = fcmp oeq x86_fp80 %tmp, %tmp1 ; [#uses=1]
+ br i1 %cmp, label %if.then, label %if.end
+
+cond.false: ; preds = %entry
+ %tmp2 = load x86_fp80* %x.addr ; [#uses=1]
+ %tmp3 = load x86_fp80* %x.addr ; [#uses=1]
+ %cmp4 = fcmp une x86_fp80 %tmp2, %tmp3 ; [#uses=1]
+ br i1 %cmp4, label %if.then, label %if.end
+
+if.then: ; preds = %cond.false, %cond.true
+ br label %if.end
+
+if.end: ; preds = %if.then, %cond.false, %cond.true
+ ret void
+}
From sabre at nondot.org Tue Sep 8 00:14:44 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 05:14:44 -0000
Subject: [llvm-commits] [llvm] r81188 -
/llvm/trunk/docs/WritingAnLLVMPass.html
Message-ID: <200909080514.n885EiPs029392@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Sep 8 00:14:44 2009
New Revision: 81188
URL: http://llvm.org/viewvc/llvm-project?rev=81188&view=rev
Log:
update this to use raw_ostream
Modified:
llvm/trunk/docs/WritingAnLLVMPass.html
Modified: llvm/trunk/docs/WritingAnLLVMPass.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/WritingAnLLVMPass.html?rev=81188&r1=81187&r2=81188&view=diff
==============================================================================
--- llvm/trunk/docs/WritingAnLLVMPass.html (original)
+++ llvm/trunk/docs/WritingAnLLVMPass.html Tue Sep 8 00:14:44 2009
@@ -223,12 +223,14 @@
Which are needed because we are writing a Pass, and
+href="http://llvm.org/doxygen/classllvm_1_1Pass.html">Pass,
we are operating on Function's.
+href="http://llvm.org/doxygen/classllvm_1_1Function.html">Function's,
+and we will be doing some printing.
Next we have:
@@ -273,7 +275,7 @@
virtual bool runOnFunction(Function &F) {
- llvm::cerr << "Hello: " << F.getName() << "\n";
+ errs() << "Hello: " << F.getName() << "\n";
return false;
}
}; // end of struct Hello
@@ -312,6 +314,7 @@
#include "llvm/Pass.h"
#include "llvm/Function.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -322,7 +325,7 @@
Hello() : FunctionPass(&ID) {}
virtual bool runOnFunction(Function &F) {
- llvm::cerr << "Hello: " << F.getName() << "\n";
+ errs() << "Hello: " << F.getName() << "\n";
return false;
}
};
From sabre at nondot.org Tue Sep 8 00:15:50 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 08 Sep 2009 05:15:50 -0000
Subject: [llvm-commits] [llvm] r81189 -
/llvm/trunk/docs/ProgrammersManual.html
Message-ID: <200909080515.n885Fo2R029530@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Sep 8 00:15:50 2009
New Revision: 81189
URL: http://llvm.org/viewvc/llvm-project?rev=81189&view=rev
Log:
llvm::cerr is gone.
Modified:
llvm/trunk/docs/ProgrammersManual.html
Modified: llvm/trunk/docs/ProgrammersManual.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ProgrammersManual.html?rev=81189&r1=81188&r2=81189&view=diff
==============================================================================
--- llvm/trunk/docs/ProgrammersManual.html (original)
+++ llvm/trunk/docs/ProgrammersManual.html Tue Sep 8 00:15:50 2009
@@ -1654,7 +1654,7 @@
for (Function::iterator i = func->begin(), e = func->end(); i != e; ++i)
// Print out the name of the basic block if it has one, and then the
// number of instructions that it contains
- llvm::cerr << "Basic block (name=" << i->getName() << ") has "
+ errs() << "Basic block (name=" << i->getName() << ") has "
<< i->size() << " instructions.\n";
@@ -1687,14 +1687,14 @@
for (BasicBlock::iterator i = blk->begin(), e = blk->end(); i != e; ++i)
// The next statement works since operator<<(ostream&,...)
// is overloaded for Instruction&
- llvm::cerr << *i << "\n";
+ errs() << *i << "\n";
However, this isn't really the best way to print out the contents of a
BasicBlock! Since the ostream operators are overloaded for virtually
anything you'll care about, you could have just invoked the print routine on the
-basic block itself: llvm::cerr << *blk << "\n";.
+basic block itself: errs() << *blk << "\n";.
@@ -1720,7 +1720,7 @@
// F is a pointer to a Function instance
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
- llvm::cerr << *I << "\n";
+ errs() << *I << "\n";
@@ -1799,7 +1799,7 @@
void printNextInstruction(Instruction* inst) {
BasicBlock::iterator it(inst);
++it; // After this line, it refers to the instruction after *inst
- if (it != inst->getParent()->end()) llvm::cerr << *it << "\n";
+ if (it != inst->getParent()->end()) errs() << *it << "\n";
}
@@ -1917,8 +1917,8 @@
for (Value::use_iterator i = F->use_begin(), e = F->use_end(); i != e; ++i)
if (Instruction *Inst = dyn_cast<Instruction>(*i)) {
- llvm::cerr << "F is used in instruction:\n";
- llvm::cerr << *Inst << "\n";
+ errs() << "F is used in instruction:\n";
+ errs() << *Inst << "\n";
}
From daniel at zuster.org Tue Sep 8 00:31:18 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Tue, 08 Sep 2009 05:31:18 -0000
Subject: [llvm-commits] [llvm] r81190 - in /llvm/trunk:
docs/CommandGuide/lit.pod utils/lit/ utils/lit/LitConfig.py
utils/lit/LitFormats.py utils/lit/ProgressBar.py utils/lit/ShCommands.py
utils/lit/ShTest.py utils/lit/ShUtil.py utils/lit/TODO utils/lit/TclTest.py
utils/lit/TclUtil.py utils/lit/Test.py utils/lit/TestRunner.py
utils/lit/TestingConfig.py utils/lit/Util.py utils/lit/lit.py
Message-ID: <200909080531.n885VJbj031496@zion.cs.uiuc.edu>
Author: ddunbar
Date: Tue Sep 8 00:31:18 2009
New Revision: 81190
URL: http://llvm.org/viewvc/llvm-project?rev=81190&view=rev
Log:
Add 'lit' testing tool.
- make install && man $(llvm-config --prefix)/share/man/man1/lit.1 for more
information.
Added:
llvm/trunk/docs/CommandGuide/lit.pod
llvm/trunk/utils/lit/
llvm/trunk/utils/lit/LitConfig.py
llvm/trunk/utils/lit/LitFormats.py
llvm/trunk/utils/lit/ProgressBar.py
llvm/trunk/utils/lit/ShCommands.py
llvm/trunk/utils/lit/ShTest.py
llvm/trunk/utils/lit/ShUtil.py
llvm/trunk/utils/lit/TODO
llvm/trunk/utils/lit/TclTest.py
llvm/trunk/utils/lit/TclUtil.py
llvm/trunk/utils/lit/Test.py
llvm/trunk/utils/lit/TestRunner.py
llvm/trunk/utils/lit/TestingConfig.py
llvm/trunk/utils/lit/Util.py
llvm/trunk/utils/lit/lit.py (with props)
Added: llvm/trunk/docs/CommandGuide/lit.pod
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/lit.pod?rev=81190&view=auto
==============================================================================
--- llvm/trunk/docs/CommandGuide/lit.pod (added)
+++ llvm/trunk/docs/CommandGuide/lit.pod Tue Sep 8 00:31:18 2009
@@ -0,0 +1,222 @@
+=pod
+
+=head1 NAME
+
+lit - LLVM Integrated Tester
+
+=head1 SYNOPSIS
+
+B [I] [I]
+
+=head1 DESCRIPTION
+
+B is a portable tool for executing LLVM and Clang style test suites,
+summarizing their results, and providing indication of failures. B is
+designed to be a lightweight testing tool with as simple a user interface as
+possible.
+
+B should be run with one or more I to run specified on the command
+line. Tests can be either individual test files or directories to search for
+tests (see L<"TEST DISCOVERY">).
+
+Each specified test will be executed (potentially in parallel) and once all
+tests have been run B will print summary information on the number of tests
+which passed or failed (see L<"TEST STATUS RESULTS">). The B program will
+execute with a non-zero exit code if any tests fail.
+
+By default B will use a succinct progress display and will only print
+summary information for test failures. See L<"OUTPUT OPTIONS"> for options
+controlling the B progress display and output.
+
+B also includes a number of options for controlling how tests are exected
+(specific features may depend on the particular test format). See L<"EXECUTION
+OPTIONS"> for more information.
+
+Finally, B also supports additional options for only running a subset of
+the options specified on the command line, see L<"SELECTION OPTIONS"> for
+more information.
+
+=head1 GENERAL OPTIONS
+
+=over
+
+=item B<-h>, B<--help>
+
+Show the B help message.
+
+=item B<-j> I, B<--threads>=I
+
+Run I tests in parallel. By default, this is automatically chose to match the
+number of detected available CPUs.
+
+=back
+
+=head1 OUTPUT OPTIONS
+
+=over
+
+=item B<-q>, B<--quiet>
+
+Suppress any output except for test failures.
+
+=item B<-s>, B<--succinct>
+
+Show less output, for example don't show information on tests that pass.
+
+=item B<-v>, B<--verbose>
+
+Show more information on test failures, for example the entire test output
+instead of just the test result.
+
+=item B<--no-progress-bar>
+
+Do not use curses based progress bar.
+
+=back
+
+=head1 EXECUTION OPTIONS
+
+=over
+
+=item B<--path>=I
+
+Specify an addition I to use when searching for executables in tests.
+
+=item B<--vg>
+
+Run individual tests under valgrind (using the memcheck tool). The
+I<--error-exitcode> argument for valgrind is used so that valgrind failures will
+cause the program to exit with a non-zero status.
+
+=item B<--vg-arg>=I
+
+When I<--vg> is used, specify an additional argument to pass to valgrind itself.
+
+=item B<--time-tests>
+
+Track the wall time individual tests take to execute and includes the results in
+the summary output. This is useful for determining which tests in a test suite
+take the most time to execute. Note that this option is most useful with I<-j
+1>.
+
+=back
+
+=head1 SELECTION OPTIONS
+
+=over
+
+=item B<--max-tests>=I
+
+Run at most I tests and then terminate.
+
+=item B<--max-time>=I
+
+Spend at most I seconds (approximately) running tests and then terminate.
+
+=item B<--shuffle>
+
+Run the tests in a random order.
+
+=back
+
+=head1 ADDITIONAL OPTIONS
+
+=over
+
+=item B<--debug>
+
+Run B in debug mode, for debugging configuration issues and B itself.
+
+=item B<--show-suites>
+
+List the discovered test suites as part of the standard output.
+
+=item B<--no-tcl-as-sh>
+
+Run Tcl scripts internally (instead of converting to shell scripts).
+
+=back
+
+=head1 EXIT STATUS
+
+B will exit with an exit code of 1 if there are any FAIL or XPASS
+results. Otherwise, it will exit with the status 0. Other exit codes used for
+non-test related failures (for example a user error or an internal program
+error).
+
+=head1 TEST DISCOVERY
+
+The inputs passed to B can be either individual tests, or entire
+directories or hierarchies of tests to run. When B starts up, the first
+thing it does is convert the inputs into a complete list of tests to run as part
+of I.
+
+In the B model, every test must exist inside some I. B
+resolves the inputs specified on the command line to test suites by searching
+upwards from the input path until it finds a I or I
+file. These files serve as both a marker of test suites and as configuration
+files which B loads in order to understand how to find and run the tests
+inside the test suite.
+
+Once B has mapped the inputs into test suites it traverses the list of
+inputs adding tests for individual files and recursively searching for tests in
+directories.
+
+This behavior makes it easy to specify a subset of tests to run, while still
+allowing the test suite configuration to control exactly how tests are
+interpreted. In addition, B always identifies tests by the test suite they
+are in, and their relative path inside the test suite. For appropriately
+configured projects, this allows B to provide convenient and flexible
+support for out-of-tree builds.
+
+=head1 TEST STATUS RESULTS
+
+Each test ultimately produces one of the following six results:
+
+=over
+
+=item B
+
+The test succeeded.
+
+=item B
+
+The test failed, but that is expected. This is used for test formats which allow
+specifying that a test does not currently work, but wish to leave it in the test
+suite.
+
+=item B
+
+The test succeeded, but it was expected to fail. This is used for tests which
+were specified as expected to fail, but are now succeeding (generally because
+the feautre they test was broken and has been fixed).
+
+=item B
+
+The test failed.
+
+=item B
+
+The test result could not be determined. For example, this occurs when the test
+could not be run, the test itself is invalid, or the test was interrupted.
+
+=item B
+
+The test is not supported in this environment. This is used by test formats
+which can report unsupported tests.
+
+=back
+
+Depending on the test format tests may produce additional information about
+their status (generally only for failures). See the L