[llvm-commits] CVS: llvm/include/llvm/Target/TargetInstrInfo.h
Changes in directory llvm/include/llvm/Target: TargetInstrInfo.h updated: 1.112 -> 1.113 --- Log message: These forward declarations are not needed. --- Diffs of the changes: (+0 -5) TargetInstrInfo.h |5 - 1 files changed, 5 deletions(-) Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.112 llvm/include/llvm/Target/TargetInstrInfo.h:1.113 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.112Wed Mar 14 10:25:21 2007 +++ llvm/include/llvm/Target/TargetInstrInfo.h Fri Mar 16 03:41:06 2007 @@ -24,11 +24,6 @@ class MachineInstr; class TargetMachine; -class Value; -class Type; -class Instruction; -class Constant; -class Function; class MachineCodeForInstruction; class TargetRegisterClass; class LiveVariables; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h
Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.112 -> 1.113 --- Log message: Added isLegalAddressExpression hook to test if the given expression can be folded into target addressing mode for the given type. --- Diffs of the changes: (+7 -1) TargetLowering.h |8 +++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.112 llvm/include/llvm/Target/TargetLowering.h:1.113 --- llvm/include/llvm/Target/TargetLowering.h:1.112 Mon Mar 12 18:26:27 2007 +++ llvm/include/llvm/Target/TargetLowering.h Fri Mar 16 03:42:32 2007 @@ -855,7 +855,13 @@ //======// // Loop Strength Reduction hooks // - + + /// isLegalAddressExpression - Return true if the binary expression made up of + /// specified opcode, operands, and type can be folded into target addressing + /// mode for load / store of the given type. + virtual bool isLegalAddressExpression(unsigned Opc, Value *Op0, Value *Op1, +const Type *Ty) const; + /// isLegalAddressImmediate - Return true if the integer value can be used as /// the offset of the target addressing mode for load / store of the given /// type. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Changes in directory llvm/lib/CodeGen/SelectionDAG: TargetLowering.cpp updated: 1.96 -> 1.97 --- Log message: Added isLegalAddressExpression hook to test if the given expression can be folded into target addressing mode for the given type. --- Diffs of the changes: (+8 -0) TargetLowering.cpp |8 1 files changed, 8 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp diff -u llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.96 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.97 --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.96 Mon Mar 12 18:37:10 2007 +++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cppFri Mar 16 03:42:32 2007 @@ -1931,6 +1931,14 @@ // Loop Strength Reduction hooks //===--===// +/// isLegalAddressExpression - Return true if the binary expression made up of +/// specified opcode, operands, and type can be folded into target addressing +/// mode for load / store of the given type. +bool TargetLowering::isLegalAddressExpression(unsigned Opc, Value *Op0, + Value *Op1, const Type *Ty) const { + return false; +} + /// isLegalAddressImmediate - Return true if the integer value can be used as /// the offset of the target addressing mode for load / store of the given /// type. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelLowering.cpp ARMISelLowering.h
Changes in directory llvm/lib/Target/ARM: ARMISelLowering.cpp updated: 1.22 -> 1.23 ARMISelLowering.h updated: 1.3 -> 1.4 --- Log message: Added isLegalAddressExpression(). Only allows X +/- C for now. --- Diffs of the changes: (+21 -0) ARMISelLowering.cpp | 15 +++ ARMISelLowering.h |6 ++ 2 files changed, 21 insertions(+) Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.22 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.23 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.22Tue Mar 13 15:37:59 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Fri Mar 16 03:43:56 2007 @@ -22,6 +22,7 @@ #include "ARMTargetMachine.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" +#include "llvm/Instruction.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -1269,6 +1270,20 @@ // ARM Optimization Hooks //===--===// +/// isLegalAddressExpression - Return true if the binary expression made up of +/// specified opcode, operands, and type can be folded into target addressing +/// mode for load / store of the given type. +bool ARMTargetLowering::isLegalAddressExpression(unsigned Opc, Value *Op0, + Value *Op1, const Type *Ty) const { + if (ConstantInt *Op1C = dyn_cast(Op1)) { +if (Opc == Instruction::Add) + return isLegalAddressImmediate(Op1C->getSExtValue(), Ty); +if (Opc == Instruction::Sub) + return isLegalAddressImmediate(-Op1C->getSExtValue(), Ty); + } + return false; +} + /// isLegalAddressImmediate - Return true if the integer value can be used /// as the offset of the target addressing mode for load / store of the /// given type. Index: llvm/lib/Target/ARM/ARMISelLowering.h diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.3 llvm/lib/Target/ARM/ARMISelLowering.h:1.4 --- llvm/lib/Target/ARM/ARMISelLowering.h:1.3 Mon Mar 12 18:30:29 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.h Fri Mar 16 03:43:56 2007 @@ -80,6 +80,12 @@ virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *MBB); +/// isLegalAddressExpression - Return true if the binary expression made up +/// of specified opcode, operands, and type can be folded into target +/// addressing mode for load / store of the given type. +virtual bool isLegalAddressExpression(unsigned Opc, Value *Op0, Value *Op1, + const Type *Ty) const; + /// isLegalAddressImmediate - Return true if the integer value can be used /// as the offset of the target addressing mode for load / store of the /// given type. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.384 -> 1.385 --- Log message: Sink a binary expression into its use blocks if it is a loop invariant computation used as GEP indexes and if the expression can be folded into target addressing mode of GEP load / store use types. --- Diffs of the changes: (+92 -0) SelectionDAGISel.cpp | 92 +++ 1 files changed, 92 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.384 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.385 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.384Thu Mar 8 16:29:47 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 16 03:46:27 2007 @@ -13,6 +13,7 @@ #define DEBUG_TYPE "isel" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CallingConv.h" @@ -58,6 +59,9 @@ static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0; #endif +static cl::opt +EnableGEPIndexSink("enable-gep-index-sinking", cl::Hidden, + cl::desc("Sink invariant GEP index computation into use blocks")); //===-===// /// @@ -3703,6 +3707,8 @@ // FIXME: we only modify the CFG to split critical edges. This // updates dom and loop info. AU.addRequired(); + AU.addRequired(); + AU.setPreservesAll(); } @@ -3959,6 +3965,88 @@ return true; } +/// isLoopInvariantInst - Returns true if all operands of the instruction are +/// loop invariants in the specified loop. +static bool isLoopInvariantInst(Instruction *I, Loop *L) { + // The instruction is loop invariant if all of its operands are loop-invariant + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) +if (!L->isLoopInvariant(I->getOperand(i))) + return false; + return true; +} + +/// SinkInvariantGEPIndex - If a GEP instruction has a variable index that has +/// been hoisted out of the loop by LICM pass, sink it back into the use BB +/// if it can be determined that the index computation can be folded into the +/// addressing mode of the load / store uses. +static bool SinkInvariantGEPIndex(BinaryOperator *BinOp, LoopInfo *loopInfo, + const TargetLowering &TLI) { + if (!EnableGEPIndexSink) +return false; + + // Only look at Add / Sub for now. + if (BinOp->getOpcode() != Instruction::Add && + BinOp->getOpcode() != Instruction::Sub) +return false; + + /// InsertedOps - Only insert a duplicate in each block once. + std::map InsertedOps; + + bool MadeChange = false; + BasicBlock *DefBB = BinOp->getParent(); + for (Value::use_iterator UI = BinOp->use_begin(), E = BinOp->use_end(); + UI != E; ) { +Instruction *User = cast(*UI); + +// Preincrement use iterator so we don't invalidate it. +++UI; + +// Only look for GEP use in another block. +if (User->getParent() == DefBB) continue; + +if (isa(User)) { + BasicBlock *UserBB = User->getParent(); + Loop *L = loopInfo->getLoopFor(UserBB); + + // Only sink if expression is a loop invariant in the use BB. + if (isLoopInvariantInst(BinOp, L) && !User->use_empty()) { +const Type *UseTy = NULL; +// FIXME: We are assuming all the uses of the GEP will have the +// same type. +Instruction *GEPUser = cast(*User->use_begin()); +if (LoadInst *Load = dyn_cast(GEPUser)) + UseTy = Load->getType(); +else if (StoreInst *Store = dyn_cast(GEPUser)) + UseTy = Store->getOperand(0)->getType(); + +// Check if it is possible to fold the expression to address mode. +if (UseTy && +TLI.isLegalAddressExpression(Instruction::Add, BinOp->getOperand(0), + BinOp->getOperand(1), UseTy)) { + // Sink it into user block. + BinaryOperator *&InsertedOp = InsertedOps[UserBB]; + if (!InsertedOp) { +BasicBlock::iterator InsertPt = UserBB->begin(); +while (isa(InsertPt)) ++InsertPt; + +InsertedOp = + BinaryOperator::create(BinOp->getOpcode(), BinOp->getOperand(0), + BinOp->getOperand(1), "", InsertPt); + } + + User->replaceUsesOfWith(BinOp, InsertedOp); + MadeChange = true; +} + } +} + } + + if (BinOp->use_empty()) + BinOp->eraseFromParent(); + + return MadeChange; +} + /// SplitEdgeNicely - Split the critical edge from TI to it's specified /// successor if it will improve codegen. We only do this if the successor has @@ -4021,6 +4109,8 @@ RegMap = MF.getSSARegMap(); DOUT << "\n\n\n=== " << Fn.getName() << "\n"; + LoopInfo *loopInfo = &getAnalysis(); + // F
[llvm-commits] CVS: llvm-test/Makefile.programs
Changes in directory llvm-test: Makefile.programs updated: 1.259 -> 1.260 --- Log message: Test GEP index sinking as llcbeta. --- Diffs of the changes: (+2 -1) Makefile.programs |3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm-test/Makefile.programs diff -u llvm-test/Makefile.programs:1.259 llvm-test/Makefile.programs:1.260 --- llvm-test/Makefile.programs:1.259 Mon Mar 5 22:53:45 2007 +++ llvm-test/Makefile.programs Fri Mar 16 03:47:44 2007 @@ -223,7 +223,8 @@ LLCBETAOPTION := -sched=simple endif ifeq ($(ARCH),x86) -LLCBETAOPTION := --enable-tail-merge +LLCBETAOPTION := -enable-gep-index-sinking +#--enable-tail-merge #-regalloc=local -fast endif ifeq ($(ARCH),Sparc) ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/test/CodeGen/X86/mmx-arith.ll
Changes in directory llvm/test/CodeGen/X86: mmx-arith.ll updated: 1.3 -> 1.4 --- Log message: And now support for MMX logical operations. --- Diffs of the changes: (+89 -59) mmx-arith.ll | 148 +++ 1 files changed, 89 insertions(+), 59 deletions(-) Index: llvm/test/CodeGen/X86/mmx-arith.ll diff -u llvm/test/CodeGen/X86/mmx-arith.ll:1.3 llvm/test/CodeGen/X86/mmx-arith.ll:1.4 --- llvm/test/CodeGen/X86/mmx-arith.ll:1.3 Thu Mar 15 16:24:36 2007 +++ llvm/test/CodeGen/X86/mmx-arith.ll Fri Mar 16 04:44:46 2007 @@ -4,28 +4,37 @@ define void @foo(<8 x i8>* %A, <8 x i8>* %B) { entry: - %tmp5 = load <8 x i8>* %A ; <<8 x i8>> [#uses=1] + %tmp1 = load <8 x i8>* %A ; <<8 x i8>> [#uses=1] + %tmp3 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp4 = add <8 x i8> %tmp1, %tmp3 ; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp4, <8 x i8>* %A %tmp7 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] - %tmp8 = add <8 x i8> %tmp5, %tmp7 ; <<8 x i8>> [#uses=2] - store <8 x i8> %tmp8, <8 x i8>* %A - %tmp14 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] - %tmp25 = tail call <8 x i8> @llvm.x86.mmx.padds.b( <8 x i8> %tmp14, <8 x i8> %tmp8 ); <<8 x i8>> [#uses=2] - store <8 x i8> %tmp25, <8 x i8>* %B - %tmp36 = load <8 x i8>* %A ; <<8 x i8>> [#uses=1] - %tmp49 = tail call <8 x i8> @llvm.x86.mmx.paddus.b( <8 x i8> %tmp36, <8 x i8> %tmp25 ) ; <<8 x i8>> [#uses=2] - store <8 x i8> %tmp49, <8 x i8>* %B - %tmp58 = load <8 x i8>* %A ; <<8 x i8>> [#uses=1] - %tmp61 = sub <8 x i8> %tmp58, %tmp49; <<8 x i8>> [#uses=2] - store <8 x i8> %tmp61, <8 x i8>* %B - %tmp64 = load <8 x i8>* %A ; <<8 x i8>> [#uses=1] - %tmp80 = tail call <8 x i8> @llvm.x86.mmx.psubs.b( <8 x i8> %tmp61, <8 x i8> %tmp64 ) ; <<8 x i8>> [#uses=2] - store <8 x i8> %tmp80, <8 x i8>* %A - %tmp89 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] - %tmp105 = tail call <8 x i8> @llvm.x86.mmx.psubus.b( <8 x i8> %tmp80, <8 x i8> %tmp89 ) ; <<8 x i8>> [#uses=1] - store <8 x i8> %tmp105, <8 x i8>* %A -%tmp13 = load <8 x i8>* %A ; <<8 x i8>> [#uses=1] -%tmp16 = mul <8 x i8> %tmp13, %tmp105; <<8 x i8>> [#uses=1] -store <8 x i8> %tmp16, <8 x i8>* %B + %tmp12 = tail call <8 x i8> @llvm.x86.mmx.padds.b( <8 x i8> %tmp4, <8 x i8> %tmp7 ) ; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp12, <8 x i8>* %A + %tmp16 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp21 = tail call <8 x i8> @llvm.x86.mmx.paddus.b( <8 x i8> %tmp12, <8 x i8> %tmp16 ) ; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp21, <8 x i8>* %A + %tmp27 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp28 = sub <8 x i8> %tmp21, %tmp27; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp28, <8 x i8>* %A + %tmp31 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp36 = tail call <8 x i8> @llvm.x86.mmx.psubs.b( <8 x i8> %tmp28, <8 x i8> %tmp31 ) ; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp36, <8 x i8>* %A + %tmp40 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp45 = tail call <8 x i8> @llvm.x86.mmx.psubus.b( <8 x i8> %tmp36, <8 x i8> %tmp40 ) ; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp45, <8 x i8>* %A + %tmp51 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp52 = mul <8 x i8> %tmp45, %tmp51; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp52, <8 x i8>* %A + %tmp57 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp58 = and <8 x i8> %tmp52, %tmp57; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp58, <8 x i8>* %A + %tmp63 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp64 = or <8 x i8> %tmp58, %tmp63 ; <<8 x i8>> [#uses=2] + store <8 x i8> %tmp64, <8 x i8>* %A + %tmp69 = load <8 x i8>* %B ; <<8 x i8>> [#uses=1] + %tmp70 = xor <8 x i8> %tmp64, %tmp69; <<8 x i8>> [#uses=1] + store <8 x i8> %tmp70, <8 x i8>* %A tail call void @llvm.x86.mmx.emms( ) ret void } @@ -37,55 +46,68 @@ %tmp4 = add <2 x i32> %tmp1, %tmp3 ; <<2 x i32>> [#uses=2] store <2 x i32> %tmp4, <2 x i32>* %A %tmp9 = load <2 x i32>* %B ; <<2 x i32>> [#uses=1] - %tmp10 = sub <2 x i32> %tmp4, %tmp9 ; <<2 x i32>> [#uses=1] - store <2 x i32> %tmp10, <2 x i32>* %B -%tmp13 = load <2 x i32>* %A ; <<2 x i32>> [#uses=1] -%tmp16 = mul <2 x i32> %tmp13, %tmp10 ; <<2 x i32>> [#uses=1] -stor
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86InstrMMX.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.370 -> 1.371 X86InstrMMX.td updated: 1.20 -> 1.21 --- Log message: And now support for MMX logical operations. --- Diffs of the changes: (+54 -2) X86ISelLowering.cpp | 18 ++ X86InstrMMX.td | 38 -- 2 files changed, 54 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.370 llvm/lib/Target/X86/X86ISelLowering.cpp:1.371 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.370 Thu Mar 15 16:24:36 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 16 04:44:46 2007 @@ -328,6 +328,24 @@ setOperationAction(ISD::MULHS, MVT::v4i16, Legal); setOperationAction(ISD::MUL,MVT::v4i16, Legal); +setOperationAction(ISD::AND,MVT::v8i8, Promote); +AddPromotedToType (ISD::AND,MVT::v8i8, MVT::v2i32); +setOperationAction(ISD::AND,MVT::v4i16, Promote); +AddPromotedToType (ISD::AND,MVT::v4i16, MVT::v2i32); +setOperationAction(ISD::AND,MVT::v2i32, Legal); + +setOperationAction(ISD::OR, MVT::v8i8, Promote); +AddPromotedToType (ISD::OR, MVT::v8i8, MVT::v2i32); +setOperationAction(ISD::OR, MVT::v4i16, Promote); +AddPromotedToType (ISD::OR, MVT::v4i16, MVT::v2i32); +setOperationAction(ISD::OR, MVT::v2i32, Legal); + +setOperationAction(ISD::XOR,MVT::v8i8, Promote); +AddPromotedToType (ISD::XOR,MVT::v8i8, MVT::v2i32); +setOperationAction(ISD::XOR,MVT::v4i16, Promote); +AddPromotedToType (ISD::XOR,MVT::v4i16, MVT::v2i32); +setOperationAction(ISD::XOR,MVT::v2i32, Legal); + setOperationAction(ISD::LOAD, MVT::v8i8, Promote); AddPromotedToType (ISD::LOAD, MVT::v8i8, MVT::v2i32); setOperationAction(ISD::LOAD, MVT::v4i16, Promote); Index: llvm/lib/Target/X86/X86InstrMMX.td diff -u llvm/lib/Target/X86/X86InstrMMX.td:1.20 llvm/lib/Target/X86/X86InstrMMX.td:1.21 --- llvm/lib/Target/X86/X86InstrMMX.td:1.20 Thu Mar 15 16:24:36 2007 +++ llvm/lib/Target/X86/X86InstrMMX.td Fri Mar 16 04:44:46 2007 @@ -63,9 +63,7 @@ (bitconvert (loadv2i32 addr:$src2)]>; } -} -let isTwoAddress = 1 in { multiclass MMXI_binop_rm_int opc, string OpcodeStr, Intrinsic IntId, bit Commutable = 0> { def rr : MMXI; } + + // MMXI_binop_rm_v2i32 - Simple MMX binary operator whose type is v2i32. + // + // FIXME: we could eliminate this and use MMXI_binop_rm instead if tblgen knew + // to collapse (bitconvert VT to VT) into its operand. + // + multiclass MMXI_binop_rm_v2i32 opc, string OpcodeStr, SDNode OpNode, + bit Commutable = 0> { +def rr : MMXI { + let isCommutable = Commutable; +} +def rm : MMXI; + } } //===--===// @@ -116,6 +132,24 @@ defm MMX_PMULHW : MMXI_binop_rm_int<0xE5, "pmulhw" , int_x86_mmx_pmulh_w , 1>; defm MMX_PMADDWD : MMXI_binop_rm_int<0xF5, "pmaddwd", int_x86_mmx_pmadd_wd, 1>; +// Logical Instructions +defm MMX_PAND : MMXI_binop_rm_v2i32<0xDB, "pand", and, 1>; +defm MMX_POR : MMXI_binop_rm_v2i32<0xEB, "por" , or, 1>; +defm MMX_PXOR : MMXI_binop_rm_v2i32<0xEF, "pxor", xor, 1>; + +let isTwoAddress = 1 in { + def MMX_PANDNrr : MMXI<0xDF, MRMSrcReg, + (ops VR64:$dst, VR64:$src1, VR64:$src2), + "pandn {$src2, $dst|$dst, $src2}", + [(set VR64:$dst, (v2i32 (and (vnot VR64:$src1), + VR64:$src2)))]>; + def MMX_PANDNrm : MMXI<0xDF, MRMSrcMem, + (ops VR64:$dst, VR64:$src1, i64mem:$src2), + "pandn {$src2, $dst|$dst, $src2}", + [(set VR64:$dst, (v2i32 (and (vnot VR64:$src1), + (load addr:$src2]>; +} + // Move Instructions def MOVD64rr : MMXI<0x6E, MRMSrcReg, (ops VR64:$dst, GR32:$src), "movd {$src, $dst|$dst, $src}", []>; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
Re: [llvm-commits] llvm-gcc: emit switch cases with a wide range as a conditional branch
> I am testing the following patch. While I was there, I made it agnostic > as to the signedness of the switch expression and cases (in Ada they can > be unsigned). I forgot to emit a new BB after the unconditional branch to the default label. Attached patch is otherwise the same as the previous one. Duncan. Index: gcc.llvm.master/gcc/llvm-convert.cpp === --- gcc.llvm.master.orig/gcc/llvm-convert.cpp 2007-03-15 15:19:45.0 +0100 +++ gcc.llvm.master/gcc/llvm-convert.cpp 2007-03-16 14:24:44.0 +0100 @@ -1666,6 +1666,7 @@ // Emit the condition. Value *SwitchExp = Emit(SWITCH_COND(exp), 0); + bool ExpIsSigned = !TYPE_UNSIGNED(TREE_TYPE(SWITCH_COND(exp))); // Emit the switch instruction. SwitchInst *SI = new SwitchInst(SwitchExp, CurBB, @@ -1673,39 +1674,68 @@ EmitBlock(new BasicBlock("")); SI->setSuccessor(0, CurBB); // Default location starts out as fall-through - // Output the body of the switch. - if (SWITCH_BODY(exp)) -Emit(SWITCH_BODY(exp), 0); - + assert(!SWITCH_BODY(exp) && "not a gimple switch?"); + + BasicBlock *DefaultDest = NULL; for (unsigned i = 0, e = TREE_VEC_LENGTH(Cases); i != e; ++i) { BasicBlock *Dest = getLabelDeclBlock(CASE_LABEL(TREE_VEC_ELT(Cases, i))); -if (CASE_LOW(TREE_VEC_ELT(Cases, i)) == 0) { - SI->setSuccessor(0, Dest); // Change the default destination. + +tree low = CASE_LOW(TREE_VEC_ELT(Cases, i)); +if (!low) { + DefaultDest = Dest; continue; } // Convert the integer to the right type. -Value *Val = Emit(CASE_LOW(TREE_VEC_ELT(Cases, i)), 0); -Val = CastToSIntType(Val, SwitchExp->getType()); -ConstantInt *ValC = cast(Val); -if (CASE_HIGH(TREE_VEC_ELT(Cases, i)) == 0) { - SI->addCase(ValC, Dest); // Single destination. +Value *Val = Emit(low, 0); +Val = CastToAnyType(Val, !TYPE_UNSIGNED(TREE_TYPE(low)), +SwitchExp->getType(), ExpIsSigned); +ConstantInt *LowC = cast(Val); + +tree high = CASE_HIGH(TREE_VEC_ELT(Cases, i)); +if (!high) { + SI->addCase(LowC, Dest); // Single destination. continue; } -// Otherwise, we have a range, like 'case 1 ... 17'. Add all of the -// necessary successors to the switch. -Val = Emit(CASE_HIGH(TREE_VEC_ELT(Cases, i)), 0); -// Make sure the case value is the same type as the switch expression (int) -Val = CastToSIntType(Val, SwitchExp->getType()); -ConstantInt *HiC = cast(Val); -Constant *OneC = ConstantInt::get(ValC->getType(), 1); -while (1) { - SI->addCase(ValC, Dest); - if (ValC == HiC) break; // Emitted the last one. - ValC = cast(ConstantExpr::getAdd(ValC, OneC)); +// Otherwise, we have a range, like 'case 1 ... 17'. +Val = Emit(high, 0); +// Make sure the case value is the same type as the switch expression +Val = CastToAnyType(Val, !TYPE_UNSIGNED(TREE_TYPE(high)), +SwitchExp->getType(), ExpIsSigned); +ConstantInt *HighC = cast(Val); + +APInt Range = HighC->getValue() - LowC->getValue(); +if (Range.ult(APInt(Range.getBitWidth(), 64))) { + // Add all of the necessary successors to the switch. + APInt CurrentValue = LowC->getValue(); + while (1) { +SI->addCase(LowC, Dest); +if (LowC == HighC) break; // Emitted the last one. +CurrentValue++; +LowC = ConstantInt::get(CurrentValue); + } +} else { + // The range is too big to add to the switch - emit an "if". + Value *Diff = BinaryOperator::create(Instruction::Sub, SwitchExp, LowC, + "tmp", CurBB); + Value *Cond = new ICmpInst(ICmpInst::ICMP_ULE, Diff, + ConstantInt::get(Range), "tmp", CurBB); + BasicBlock *False_Block = new BasicBlock("case_false"); + new BranchInst(Dest, False_Block, Cond, CurBB); + EmitBlock(False_Block); } } + + if (DefaultDest) +if (SI->getSuccessor(0) == CurBB) + SI->setSuccessor(0, DefaultDest); +else { + new BranchInst(DefaultDest, CurBB); + // Emit a "fallthrough" block, which is almost certainly dead. + EmitBlock(new BasicBlock("")); +} + return 0; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.385 -> 1.386 --- Log message: Stupid bug. --- Diffs of the changes: (+1 -1) SelectionDAGISel.cpp |2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.385 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.386 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.385Fri Mar 16 03:46:27 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 16 12:50:20 2007 @@ -4009,7 +4009,7 @@ Loop *L = loopInfo->getLoopFor(UserBB); // Only sink if expression is a loop invariant in the use BB. - if (isLoopInvariantInst(BinOp, L) && !User->use_empty()) { + if (L && isLoopInvariantInst(BinOp, L) && !User->use_empty()) { const Type *UseTy = NULL; // FIXME: We are assuming all the uses of the GEP will have the // same type. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.386 -> 1.387 --- Log message: Turn on GEP index sinking by default. --- Diffs of the changes: (+0 -7) SelectionDAGISel.cpp |7 --- 1 files changed, 7 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.386 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.387 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.386Fri Mar 16 12:50:20 2007 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Mar 16 13:32:30 2007 @@ -59,10 +59,6 @@ static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0; #endif -static cl::opt -EnableGEPIndexSink("enable-gep-index-sinking", cl::Hidden, - cl::desc("Sink invariant GEP index computation into use blocks")); - //===-===// /// /// RegisterScheduler class - Track the registration of instruction schedulers. @@ -3981,9 +3977,6 @@ /// addressing mode of the load / store uses. static bool SinkInvariantGEPIndex(BinaryOperator *BinOp, LoopInfo *loopInfo, const TargetLowering &TLI) { - if (!EnableGEPIndexSink) -return false; - // Only look at Add / Sub for now. if (BinOp->getOpcode() != Instruction::Add && BinOp->getOpcode() != Instruction::Sub) ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/ARM/ARMISelLowering.cpp
Changes in directory llvm/lib/Target/ARM: ARMISelLowering.cpp updated: 1.23 -> 1.24 --- Log message: Only ARMv6 has BSWAP. Fix MultiSource/Applications/aha test. --- Diffs of the changes: (+4 -0) ARMISelLowering.cpp |4 1 files changed, 4 insertions(+) Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.23 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.24 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.23Fri Mar 16 03:43:56 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Fri Mar 16 17:54:16 2007 @@ -159,6 +159,10 @@ if (!Subtarget->hasV5TOps() || Subtarget->isThumb()) setOperationAction(ISD::CTLZ, MVT::i32, Expand); + // Only ARMv6 has BSWAP. + if (!Subtarget->hasV6Ops()) + setOperationAction(ISD::BSWAP, MVT::i32, Expand); + // These are expanded into libcalls. setOperationAction(ISD::SDIV, MVT::i32, Expand); setOperationAction(ISD::UDIV, MVT::i32, Expand); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.371 -> 1.372 --- Log message: Support 'I' inline asm constraint. --- Diffs of the changes: (+11 -0) X86ISelLowering.cpp | 11 +++ 1 files changed, 11 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.371 llvm/lib/Target/X86/X86ISelLowering.cpp:1.372 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.371 Fri Mar 16 04:44:46 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 16 19:13:28 2007 @@ -4523,6 +4523,17 @@ isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) { switch (Constraint) { default: break; + case 'I': +if (isa(Op)) { + unsigned Value = cast(Op)->getValue(); + if (Value >= 0 && Value <= 31) +return Op; + else +return SDOperand(0,0); +} else { +return SDOperand(0,0); +} +break; case 'i': // Literal immediates are always ok. if (isa(Op)) return Op; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/test/CodeGen/X86/2007-03-16-InlineAsm.ll
Changes in directory llvm/test/CodeGen/X86: 2007-03-16-InlineAsm.ll added (r1.1) --- Log message: Test case for X86 inline asm constraint 'I' --- Diffs of the changes: (+28 -0) 2007-03-16-InlineAsm.ll | 28 1 files changed, 28 insertions(+) Index: llvm/test/CodeGen/X86/2007-03-16-InlineAsm.ll diff -c /dev/null llvm/test/CodeGen/X86/2007-03-16-InlineAsm.ll:1.1 *** /dev/null Fri Mar 16 19:15:02 2007 --- llvm/test/CodeGen/X86/2007-03-16-InlineAsm.ll Fri Mar 16 19:14:52 2007 *** *** 0 --- 1,28 + ; RUN: llvm-as < %s | llc -march=x86 + + ; ModuleID = 'a.bc' + implementation ; Functions: + + define i32 @foo(i32 %A, i32 %B) { + entry: + %A_addr = alloca i32; [#uses=2] + %B_addr = alloca i32; [#uses=1] + %retval = alloca i32, align 4 ; [#uses=2] + %tmp = alloca i32, align 4 ; [#uses=2] + %ret = alloca i32, align 4 ; [#uses=2] + "alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store i32 %A, i32* %A_addr + store i32 %B, i32* %B_addr + %tmp1 = load i32* %A_addr ; [#uses=1] + %tmp2 = call i32 asm "roll $1,$0", "=r,I,0,~{dirflag},~{fpsr},~{flags},~{cc}"( i32 7, i32 %tmp1 ) ; [#uses=1] + store i32 %tmp2, i32* %ret + %tmp3 = load i32* %ret ; [#uses=1] + store i32 %tmp3, i32* %tmp + %tmp4 = load i32* %tmp ; [#uses=1] + store i32 %tmp4, i32* %retval + br label %return + + return: ; preds = %entry + %retval5 = load i32* %retval; [#uses=1] + ret i32 %retval5 + } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/test/CodeGen/ARM/2007-03-15-GEP-Idx-Sink.ll
Changes in directory llvm/test/CodeGen/ARM: 2007-03-15-GEP-Idx-Sink.ll added (r1.1) --- Log message: GEP index sink test case. --- Diffs of the changes: (+73 -0) 2007-03-15-GEP-Idx-Sink.ll | 73 + 1 files changed, 73 insertions(+) Index: llvm/test/CodeGen/ARM/2007-03-15-GEP-Idx-Sink.ll diff -c /dev/null llvm/test/CodeGen/ARM/2007-03-15-GEP-Idx-Sink.ll:1.1 *** /dev/null Fri Mar 16 22:18:42 2007 --- llvm/test/CodeGen/ARM/2007-03-15-GEP-Idx-Sink.llFri Mar 16 22:18:32 2007 *** *** 0 --- 1,73 + ; RUN: llvm-as < %s | llc -march=arm && + ; RUN: llvm-as < %s | llc -march=arm -stats 2>&1 | not grep 'register spills' + + define void @foo(i8** %buf, i32 %size, i32 %col, i8* %p) { + entry: + icmp sgt i32 %size, 0 ; :0 [#uses=1] + br i1 %0, label %bb.preheader, label %return + + bb.preheader: ; preds = %entry + %tmp5.sum72 = add i32 %col, 7 ; [#uses=1] + %tmp5.sum71 = add i32 %col, 5 ; [#uses=1] + %tmp5.sum70 = add i32 %col, 3 ; [#uses=1] + %tmp5.sum69 = add i32 %col, 2 ; [#uses=1] + %tmp5.sum68 = add i32 %col, 1 ; [#uses=1] + %tmp5.sum66 = add i32 %col, 4 ; [#uses=1] + %tmp5.sum = add i32 %col, 6 ; [#uses=1] + br label %bb + + bb: ; preds = %bb, %bb.preheader + %i.073.0 = phi i32 [ 0, %bb.preheader ], [ %indvar.next, %bb ] ; [#uses=3] + %p_addr.076.0.rec = mul i32 %i.073.0, 9 ; [#uses=9] + %p_addr.076.0 = getelementptr i8* %p, i32 %p_addr.076.0.rec ; [#uses=1] + %tmp2 = getelementptr i8** %buf, i32 %i.073.0 ; [#uses=1] + %tmp3 = load i8** %tmp2 ; [#uses=8] + %tmp5 = getelementptr i8* %tmp3, i32 %col ; [#uses=1] + %tmp7 = load i8* %p_addr.076.0 ; [#uses=1] + store i8 %tmp7, i8* %tmp5 + %p_addr.076.0.sum93 = add i32 %p_addr.076.0.rec, 1 ; [#uses=1] + %tmp11 = getelementptr i8* %p, i32 %p_addr.076.0.sum93 ; [#uses=1] + %tmp13 = load i8* %tmp11; [#uses=1] + %tmp15 = getelementptr i8* %tmp3, i32 %tmp5.sum72 ; [#uses=1] + store i8 %tmp13, i8* %tmp15 + %p_addr.076.0.sum92 = add i32 %p_addr.076.0.rec, 2 ; [#uses=1] + %tmp17 = getelementptr i8* %p, i32 %p_addr.076.0.sum92 ; [#uses=1] + %tmp19 = load i8* %tmp17; [#uses=1] + %tmp21 = getelementptr i8* %tmp3, i32 %tmp5.sum71 ; [#uses=1] + store i8 %tmp19, i8* %tmp21 + %p_addr.076.0.sum91 = add i32 %p_addr.076.0.rec, 3 ; [#uses=1] + %tmp23 = getelementptr i8* %p, i32 %p_addr.076.0.sum91 ; [#uses=1] + %tmp25 = load i8* %tmp23; [#uses=1] + %tmp27 = getelementptr i8* %tmp3, i32 %tmp5.sum70 ; [#uses=1] + store i8 %tmp25, i8* %tmp27 + %p_addr.076.0.sum90 = add i32 %p_addr.076.0.rec, 4 ; [#uses=1] + %tmp29 = getelementptr i8* %p, i32 %p_addr.076.0.sum90 ; [#uses=1] + %tmp31 = load i8* %tmp29; [#uses=1] + %tmp33 = getelementptr i8* %tmp3, i32 %tmp5.sum69 ; [#uses=2] + store i8 %tmp31, i8* %tmp33 + %p_addr.076.0.sum89 = add i32 %p_addr.076.0.rec, 5 ; [#uses=1] + %tmp35 = getelementptr i8* %p, i32 %p_addr.076.0.sum89 ; [#uses=1] + %tmp37 = load i8* %tmp35; [#uses=1] + %tmp39 = getelementptr i8* %tmp3, i32 %tmp5.sum68 ; [#uses=1] + store i8 %tmp37, i8* %tmp39 + %p_addr.076.0.sum88 = add i32 %p_addr.076.0.rec, 6 ; [#uses=1] + %tmp41 = getelementptr i8* %p, i32 %p_addr.076.0.sum88 ; [#uses=1] + %tmp43 = load i8* %tmp41; [#uses=1] + store i8 %tmp43, i8* %tmp33 + %p_addr.076.0.sum87 = add i32 %p_addr.076.0.rec, 7 ; [#uses=1] + %tmp47 = getelementptr i8* %p, i32 %p_addr.076.0.sum87 ; [#uses=1] + %tmp49 = load i8* %tmp47; [#uses=1] + %tmp51 = getelementptr i8* %tmp3, i32 %tmp5.sum66 ; [#uses=1] + store i8 %tmp49, i8* %tmp51 + %p_addr.076.0.sum = add i32 %p_addr.076.0.rec, 8; [#uses=1] + %tmp53 = getelementptr i8* %p, i32 %p_addr.076.0.sum; [#uses=1] + %tmp55 = load i8* %tmp53; [#uses=1] + %tmp57 = getelementptr i8* %tmp3, i32 %tmp5.sum ; [#uses=1] + store i8 %tmp55, i8* %tmp57 + %indvar.next = add i32 %i.073.0, 1 ; [#uses=2] + icmp eq i32 %indvar.next, %size ; :1 [#uses=1] + br i1 %1, label %return, label %bb + + return: ; preds = %bb, %entry + ret void + } ___