From lattner at cs.uiuc.edu Mon Mar 10 11:09:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 11:09:01 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/NoSource/Moria-5.5.2/Makefile Message-ID: <200303101708.LAA11042@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs/NoSource/Moria-5.5.2: Makefile updated: 1.1 -> 1.2 --- Log message: Update makefile --- Diffs of the changes: Index: llvm/test/Programs/NoSource/Moria-5.5.2/Makefile diff -u llvm/test/Programs/NoSource/Moria-5.5.2/Makefile:1.1 llvm/test/Programs/NoSource/Moria-5.5.2/Makefile:1.2 --- llvm/test/Programs/NoSource/Moria-5.5.2/Makefile:1.1 Thu Jan 30 16:39:04 2003 +++ llvm/test/Programs/NoSource/Moria-5.5.2/Makefile Mon Mar 10 11:08:11 2003 @@ -1,8 +1,4 @@ LEVEL = ../../../.. - PROG = moria -USE_PRECOMPILED_BYTECODE := 1 - -include ../Makefile.multisrc - +include ../Makefile.nosource From lattner at cs.uiuc.edu Mon Mar 10 12:22:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 12:22:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/shift.ll Message-ID: <200303101821.MAA12303@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: shift.ll updated: 1.5 -> 1.6 --- Log message: Modernize testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/shift.ll diff -u llvm/test/Regression/Transforms/InstCombine/shift.ll:1.5 llvm/test/Regression/Transforms/InstCombine/shift.ll:1.6 --- llvm/test/Regression/Transforms/InstCombine/shift.ll:1.5 Tue Oct 8 11:10:35 2002 +++ llvm/test/Regression/Transforms/InstCombine/shift.ll Mon Mar 10 12:20:53 2003 @@ -8,27 +8,27 @@ implementation -int "test1"(int %A) { +int %test1(int %A) { %B = shl int %A, ubyte 0 ret int %B } -int "test2"(ubyte %A) { +int %test2(ubyte %A) { %B = shl int 0, ubyte %A ret int %B } -int "test3"(int %A) { +int %test3(int %A) { %B = shr int %A, ubyte 0 ret int %B } -int "test4"(ubyte %A) { +int %test4(ubyte %A) { %B = shr int 0, ubyte %A ret int %B } -uint "test5"(uint %A) { +uint %test5(uint %A) { %B = shr uint %A, ubyte 32 ;; shift all bits out ret uint %B } From lattner at cs.uiuc.edu Mon Mar 10 12:25:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 12:25:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/or.ll Message-ID: <200303101824.MAA12521@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: or.ll updated: 1.8 -> 1.9 --- Log message: Add test for: (A|B)^B == A & (~B) --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.8 llvm/test/Regression/Transforms/InstCombine/or.ll:1.9 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.8 Tue Feb 18 13:28:47 2003 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Mon Mar 10 12:24:04 2003 @@ -69,3 +69,9 @@ %B = or int %A, %NotA ret int %B } + +uint %test13(uint %A) { ; (A|B)^B == A & (~B) + %t1 = or uint %A, 123 + %r = xor uint %t1, 123 + ret uint %r +} From lattner at cs.uiuc.edu Mon Mar 10 12:25:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 12:25:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303101824.MAA12534@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.70 -> 1.71 --- Log message: Implement: (A|B)^B == A & (~B) --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.70 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.71 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.70 Wed Mar 5 16:33:14 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 12:24:17 2003 @@ -493,6 +493,31 @@ return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); + + + if (Instruction *Op1I = dyn_cast(Op1)) + if (Op1I->getOpcode() == Instruction::Or) + if (Op1I->getOperand(0) == Op0) { // B^(B|A) == (A|B)^B + cast(Op1I)->swapOperands(); + I.swapOperands(); + std::swap(Op0, Op1); + } else if (Op1I->getOperand(1) == Op0) { // B^(A|B) == (A|B)^B + I.swapOperands(); + std::swap(Op0, Op1); + } + + if (Instruction *Op0I = dyn_cast(Op0)) + if (Op0I->getOpcode() == Instruction::Or && Op0I->use_size() == 1) { + if (Op0I->getOperand(0) == Op1) // (B|A)^B == (A|B)^B + cast(Op0I)->swapOperands(); + if (Op0I->getOperand(1) == Op1) { // (A|B)^B == A & ~B + Value *NotB = BinaryOperator::createNot(Op1, Op1->getName()+".not", &I); + WorkList.push_back(cast(NotB)); + return BinaryOperator::create(Instruction::And, Op0I->getOperand(0), + NotB); + } + } + return Changed ? &I : 0; } From lattner at cs.uiuc.edu Mon Mar 10 13:17:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 13:17:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303101916.NAA13032@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.71 -> 1.72 --- Log message: Fix bug: (x << 100) wasn't folded to 0, but (x >> 100) was (when x is unsigned) Implement new shift optimizations for shifting the result of a shift. --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.71 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.72 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.71 Mon Mar 10 12:24:17 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 13:16:08 2003 @@ -73,7 +73,7 @@ Instruction *visitOr (BinaryOperator &I); Instruction *visitXor(BinaryOperator &I); Instruction *visitSetCondInst(BinaryOperator &I); - Instruction *visitShiftInst(Instruction &I); + Instruction *visitShiftInst(ShiftInst &I); Instruction *visitCastInst(CastInst &CI); Instruction *visitPHINode(PHINode &PN); Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP); @@ -637,7 +637,7 @@ -Instruction *InstCombiner::visitShiftInst(Instruction &I) { +Instruction *InstCombiner::visitShiftInst(ShiftInst &I) { assert(I.getOperand(1)->getType() == Type::UByteTy); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -647,15 +647,56 @@ Op0 == Constant::getNullValue(Op0->getType())) return ReplaceInstUsesWith(I, Op0); + // If this is a shift of a shift, see if we can fold the two together... + if (ShiftInst *Op0SI = dyn_cast(Op0)) { + if (isa(Op1) && isa(Op0SI->getOperand(1))) { + ConstantUInt *ShiftAmt1C = cast(Op0SI->getOperand(1)); + unsigned ShiftAmt1 = ShiftAmt1C->getValue(); + unsigned ShiftAmt2 = cast(Op1)->getValue(); + + // Check for (A << c1) << c2 and (A >> c1) >> c2 + if (I.getOpcode() == Op0SI->getOpcode()) { + unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift... + return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0), + ConstantUInt::get(Type::UByteTy, Amt)); + } + + if (I.getType()->isUnsigned()) { // Check for (A << c1) >> c2 or visaversa + // Calculate bitmask for what gets shifted off the edge... + Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); + if (I.getOpcode() == Instruction::Shr) + C = *C >> *ShiftAmt1C; + else + C = *C << *ShiftAmt1C; + assert(C && "Couldn't constant fold shift expression?"); + + Instruction *Mask = + BinaryOperator::create(Instruction::And, Op0SI->getOperand(0), + C, Op0SI->getOperand(0)->getName()+".mask",&I); + WorkList.push_back(Mask); + + // Figure out what flavor of shift we should use... + if (ShiftAmt1 == ShiftAmt2) + return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 + else if (ShiftAmt1 < ShiftAmt2) { + return new ShiftInst(I.getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); + } else { + return new ShiftInst(Op0SI->getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + } + } + } + } + // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr of // a signed value. // if (ConstantUInt *CUI = dyn_cast(Op1)) { - if (I.getOpcode() == Instruction::Shr) { - unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8; - if (CUI->getValue() >= TypeBits && !(Op0->getType()->isSigned())) - return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); - } + unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8; + if (CUI->getValue() >= TypeBits && + (!Op0->getType()->isSigned() || I.getOpcode() == Instruction::Shl)) + return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType())); // Check to see if we are shifting left by 1. If so, turn it into an add // instruction. From lattner at cs.uiuc.edu Mon Mar 10 13:17:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 13:17:02 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/shift.ll Message-ID: <200303101916.NAA13041@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: shift.ll updated: 1.6 -> 1.7 --- Log message: Add a bunch of new tests --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/shift.ll diff -u llvm/test/Regression/Transforms/InstCombine/shift.ll:1.6 llvm/test/Regression/Transforms/InstCombine/shift.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/shift.ll:1.6 Mon Mar 10 12:20:53 2003 +++ llvm/test/Regression/Transforms/InstCombine/shift.ll Mon Mar 10 13:16:20 2003 @@ -33,6 +33,11 @@ ret uint %B } +uint %test5a(uint %A) { + %B = shl uint %A, ubyte 32 ;; shift all bits out + ret uint %B +} + uint %test6(uint %A) { %B = shl uint %A, ubyte 1 ;; convert to an add instruction ret uint %B @@ -42,3 +47,28 @@ %B = shr int -1, ubyte %A ;; Always equal to -1 ret int %B } + +ubyte %test8(ubyte %A) { ;; (A << 5) << 3 === A << 8 == 0 + %B = shl ubyte %A, ubyte 5 + %C = shl ubyte %B, ubyte 3 + ret ubyte %C +} + +ubyte %test9(ubyte %A) { ;; (A << 7) >> 7 === A & 1 + %B = shl ubyte %A, ubyte 7 + %C = shr ubyte %B, ubyte 7 + ret ubyte %C +} + +ubyte %test10(ubyte %A) { ;; (A >> 7) << 7 === A & 128 + %B = shr ubyte %A, ubyte 7 + %C = shl ubyte %B, ubyte 7 + ret ubyte %C +} + +ubyte %test11(ubyte %A) { ;; (A >> 3) << 4 == (A & 0x1F) << 1 + %B = shr ubyte %A, ubyte 3 + %C = shl ubyte %B, ubyte 4 + ret ubyte %C +} + From lattner at cs.uiuc.edu Mon Mar 10 13:21:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 13:21:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303101920.NAA13073@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.72 -> 1.73 --- Log message: Minor change, no functionality diff --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.72 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.73 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.72 Mon Mar 10 13:16:08 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 13:20:30 2003 @@ -510,11 +510,11 @@ if (Op0I->getOpcode() == Instruction::Or && Op0I->use_size() == 1) { if (Op0I->getOperand(0) == Op1) // (B|A)^B == (A|B)^B cast(Op0I)->swapOperands(); - if (Op0I->getOperand(1) == Op1) { // (A|B)^B == A & ~B + if (Op0I->getOperand(1) == Op1) { // (A|B)^B == ~B & A Value *NotB = BinaryOperator::createNot(Op1, Op1->getName()+".not", &I); WorkList.push_back(cast(NotB)); - return BinaryOperator::create(Instruction::And, Op0I->getOperand(0), - NotB); + return BinaryOperator::create(Instruction::And, NotB, + Op0I->getOperand(0)); } } From lattner at cs.uiuc.edu Mon Mar 10 13:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 13:45:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/mul.ll Message-ID: <200303101944.NAA13150@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: mul.ll updated: 1.3 -> 1.4 --- Log message: Modernize testcase --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/mul.ll diff -u llvm/test/Regression/Transforms/InstCombine/mul.ll:1.3 llvm/test/Regression/Transforms/InstCombine/mul.ll:1.4 --- llvm/test/Regression/Transforms/InstCombine/mul.ll:1.3 Tue Feb 18 13:28:47 2003 +++ llvm/test/Regression/Transforms/InstCombine/mul.ll Mon Mar 10 13:44:01 2003 @@ -8,23 +8,20 @@ implementation -int "test1"(int %A) -begin +int %test1(int %A) { %B = mul int %A, 1 ret int %B -end +} -int "test2"(int %A) -begin +int %test2(int %A) { %B = mul int %A, 2 ; Should convert to an add instruction ret int %B -end +} -int "test3"(int %A) -begin +int %test3(int %A) { %B = mul int %A, 0 ; This should disappear entirely ret int %B -end +} double %test4(double %A) { %B = mul double 1.0, %A ; This is safe for FP From lattner at cs.uiuc.edu Mon Mar 10 15:44:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 15:44:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303102143.PAA14501@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.73 -> 1.74 --- Log message: Generalize (A+c1)+c2 optimization to work with all associative operators --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.73 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.74 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.73 Mon Mar 10 13:20:30 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 15:43:22 2003 @@ -109,14 +109,49 @@ RegisterOpt X("instcombine", "Combine redundant instructions"); } +// getComplexity: Assign a complexity or rank value to LLVM Values... +// 0 -> Constant, 1 -> Other, 2 -> Argument, 2 -> Unary, 3 -> OtherInst +static unsigned getComplexity(Value *V) { + if (isa(V)) { + if (BinaryOperator::isNeg(V) || BinaryOperator::isNot(V)) + return 2; + return 3; + } + if (isa(V)) return 2; + return isa(V) ? 0 : 1; +} -// Make sure that this instruction has a constant on the right hand side if it -// has any constant arguments. If not, fix it an return true. +// SimplifyCommutative - This performs a few simplifications for commutative +// operators: +// +// 1. Order operands such that they are listed from right (least complex) to +// left (most complex). This puts constants before unary operators before +// binary operators. // -static bool SimplifyBinOp(BinaryOperator &I) { - if (isa(I.getOperand(0)) && !isa(I.getOperand(1))) - return !I.swapOperands(); - return false; +// 2. Handle the case of (op (op V, C1), C2), changing it to: +// (op V, (op C1, C2)) +// +static bool SimplifyCommutative(BinaryOperator &I) { + bool Changed = false; + if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1))) + Changed = !I.swapOperands(); + + if (!I.isAssociative()) return Changed; + Instruction::BinaryOps Opcode = I.getOpcode(); + if (BinaryOperator *Op = dyn_cast(I.getOperand(0))) { + if (Op->getOpcode() == Opcode && isa(I.getOperand(1)) && + isa(Op->getOperand(1))) { + Instruction *New = BinaryOperator::create(I.getOpcode(), I.getOperand(1), + Op->getOperand(1)); + Constant *Folded = ConstantFoldInstruction(New); + delete New; + assert(Folded && "Couldn't constant fold commutative operand?"); + I.setOperand(0, Op->getOperand(0)); + I.setOperand(1, Folded); + return true; + } + } + return Changed; } // dyn_castNegInst - Given a 'sub' instruction, return the RHS of the @@ -157,7 +192,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { - bool Changed = SimplifyBinOp(I); + bool Changed = SimplifyCommutative(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); // Eliminate 'add int %X, 0' @@ -172,26 +207,6 @@ if (Value *V = dyn_castNegInst(RHS)) return BinaryOperator::create(Instruction::Sub, LHS, V); - // Simplify add instructions with a constant RHS... - if (Constant *Op2 = dyn_cast(RHS)) { - if (BinaryOperator *ILHS = dyn_cast(LHS)) { - if (ILHS->getOpcode() == Instruction::Add && - isa(ILHS->getOperand(1))) { - // Fold: - // %Y = add int %X, 1 - // %Z = add int %Y, 1 - // into: - // %Z = add int %X, 2 - // - if (Constant *Val = *Op2 + *cast(ILHS->getOperand(1))) { - I.setOperand(0, ILHS->getOperand(0)); - I.setOperand(1, Val); - return &I; - } - } - } - } - // X*C + X --> X * (C+1) if (dyn_castFoldableMul(LHS) == RHS) { Constant *CP1 = *cast(cast(LHS)->getOperand(1)) + @@ -279,7 +294,7 @@ } Instruction *InstCombiner::visitMul(BinaryOperator &I) { - bool Changed = SimplifyBinOp(I); + bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0); // Simplify mul instructions with a constant RHS... @@ -397,7 +412,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { - bool Changed = SimplifyBinOp(I); + bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // and X, X = X and X, 0 == 0 @@ -429,7 +444,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { - bool Changed = SimplifyBinOp(I); + bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // or X, X = X or X, 0 == X @@ -457,7 +472,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { - bool Changed = SimplifyBinOp(I); + bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); // xor X, X = 0 @@ -510,11 +525,11 @@ if (Op0I->getOpcode() == Instruction::Or && Op0I->use_size() == 1) { if (Op0I->getOperand(0) == Op1) // (B|A)^B == (A|B)^B cast(Op0I)->swapOperands(); - if (Op0I->getOperand(1) == Op1) { // (A|B)^B == ~B & A + if (Op0I->getOperand(1) == Op1) { // (A|B)^B == A & ~B Value *NotB = BinaryOperator::createNot(Op1, Op1->getName()+".not", &I); WorkList.push_back(cast(NotB)); - return BinaryOperator::create(Instruction::And, NotB, - Op0I->getOperand(0)); + return BinaryOperator::create(Instruction::And, Op0I->getOperand(0), + NotB); } } @@ -543,7 +558,7 @@ } Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { - bool Changed = SimplifyBinOp(I); + bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); const Type *Ty = Op0->getType(); From lattner at cs.uiuc.edu Mon Mar 10 16:40:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 16:40:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Constants.h Message-ID: <200303102239.QAA15799@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm: Constants.h updated: 1.19 -> 1.20 --- Log message: Fix ConstantUInt::isAllOnesValue --- Diffs of the changes: Index: llvm/include/llvm/Constants.h diff -u llvm/include/llvm/Constants.h:1.19 llvm/include/llvm/Constants.h:1.20 --- llvm/include/llvm/Constants.h:1.19 Thu Mar 6 15:02:43 2003 +++ llvm/include/llvm/Constants.h Mon Mar 10 16:39:01 2003 @@ -134,7 +134,6 @@ /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. virtual bool isNullValue() const { return Val.Unsigned == 0; } - virtual bool isAllOnesValue() const { return Val.Signed == -1; } virtual bool isMaxValue() const = 0; virtual bool isMinValue() const = 0; @@ -165,6 +164,8 @@ /// getValue - return the underlying value of this constant. inline int64_t getValue() const { return Val.Signed; } + virtual bool isAllOnesValue() const { return getValue() == -1; } + /// isMaxValue - Return true if this is the largest value that may be /// represented by this type. /// @@ -214,6 +215,7 @@ /// isMaxValue - Return true if this is the largest value that may be /// represented by this type. /// + virtual bool isAllOnesValue() const; virtual bool isMaxValue() const { return isAllOnesValue(); } virtual bool isMinValue() const { return getValue() == 0; } From lattner at cs.uiuc.edu Mon Mar 10 16:40:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 16:40:03 2003 Subject: [llvm-commits] CVS: llvm/lib/VMCore/Constants.cpp Message-ID: <200303102239.QAA15806@apoc.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: Constants.cpp updated: 1.33 -> 1.34 --- Log message: Fix ConstantUInt::isAllOnesValue --- Diffs of the changes: Index: llvm/lib/VMCore/Constants.cpp diff -u llvm/lib/VMCore/Constants.cpp:1.33 llvm/lib/VMCore/Constants.cpp:1.34 --- llvm/lib/VMCore/Constants.cpp:1.33 Thu Mar 6 15:02:18 2003 +++ llvm/lib/VMCore/Constants.cpp Mon Mar 10 16:39:02 2003 @@ -173,6 +173,13 @@ } } +bool ConstantUInt::isAllOnesValue() const { + unsigned TypeBits = getType()->getPrimitiveSize()*8; + uint64_t Val = ~0ULL; // All ones + Val >>= 64-TypeBits; // Shift out inappropriate bits + return getValue() == Val; +} + //===----------------------------------------------------------------------===// // ConstantXXX Classes From lattner at cs.uiuc.edu Mon Mar 10 16:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 16:45:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/and.ll mul.ll or.ll Message-ID: <200303102244.QAA15829@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: and.ll updated: 1.5 -> 1.6 mul.ll updated: 1.4 -> 1.5 or.ll updated: 1.9 -> 1.10 --- Log message: * Add testcases for associative operators * Add testcase for or ubyte, 255 which was broken before --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/and.ll diff -u llvm/test/Regression/Transforms/InstCombine/and.ll:1.5 llvm/test/Regression/Transforms/InstCombine/and.ll:1.6 --- llvm/test/Regression/Transforms/InstCombine/and.ll:1.5 Tue Feb 18 13:28:47 2003 +++ llvm/test/Regression/Transforms/InstCombine/and.ll Mon Mar 10 16:43:56 2003 @@ -42,4 +42,10 @@ %NotA = xor int %A, -1 %B = and int %A, %NotA ret int %B -} \ No newline at end of file +} + +ubyte %test8(ubyte %A) { ; AND associates + %B = and ubyte %A, 3 + %C = and ubyte %B, 4 + ret ubyte %C +} Index: llvm/test/Regression/Transforms/InstCombine/mul.ll diff -u llvm/test/Regression/Transforms/InstCombine/mul.ll:1.4 llvm/test/Regression/Transforms/InstCombine/mul.ll:1.5 --- llvm/test/Regression/Transforms/InstCombine/mul.ll:1.4 Mon Mar 10 13:44:01 2003 +++ llvm/test/Regression/Transforms/InstCombine/mul.ll Mon Mar 10 16:43:56 2003 @@ -32,3 +32,9 @@ %B = mul int %A, 8 ret int %B } + +int %test6(ubyte %A) { + %B = mul ubyte %A, 8 + %C = mul ubyte %B, 13 + ret ubyte %C +} Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.9 llvm/test/Regression/Transforms/InstCombine/or.ll:1.10 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.9 Mon Mar 10 12:24:04 2003 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Mon Mar 10 16:43:56 2003 @@ -18,6 +18,11 @@ ret int %B } +ubyte %test2a(ubyte %A) { + %B = or ubyte %A, 255 + ret ubyte %B +} + bool %test3(bool %A) { %B = or bool %A, false ret bool %B @@ -74,4 +79,15 @@ %t1 = or uint %A, 123 %r = xor uint %t1, 123 ret uint %r +} + +ubyte %test14(ubyte %A) { + %B = or ubyte %A, 254 + %C = or ubyte %B, 1 + ret ubyte %C +} +ubyte %test15(ubyte %A) { + %B = xor ubyte %A, 17 + %C = xor ubyte %B, 17 + ret ubyte %C } From lattner at cs.uiuc.edu Mon Mar 10 17:08:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 17:08:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303102307.RAA16685@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.74 -> 1.75 --- Log message: Generalize not and neg comparison testers to allow constant to be considered not'able and neg'able. This allows optimization of this: int %test4(int %A, int %B) { %a = xor int %A, -1 %c = and int %a, 5 ; 5 = ~c2 %d = xor int %c, -1 ret int %d } into this: int %test4(int %A, int %B) { ; No predecessors! %c.demorgan = or int %A, -6 ; [#uses=1] ret int %c.demorgan } --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.74 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.75 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.74 Mon Mar 10 15:43:22 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 17:06:50 2003 @@ -154,17 +154,37 @@ return Changed; } -// dyn_castNegInst - Given a 'sub' instruction, return the RHS of the -// instruction if the LHS is a constant zero (which is the 'negate' form). +// dyn_castNegVal - Given a 'sub' instruction, return the RHS of the instruction +// if the LHS is a constant zero (which is the 'negate' form). // -static inline Value *dyn_castNegInst(Value *V) { - return BinaryOperator::isNeg(V) ? - BinaryOperator::getNegArgument(cast(V)) : 0; +static inline Value *dyn_castNegVal(Value *V) { + if (BinaryOperator::isNeg(V)) + return BinaryOperator::getNegArgument(cast(V)); + + // Constants can be considered to be negated values... + if (Constant *C = dyn_cast(V)) { + Constant *NC = *Constant::getNullValue(V->getType()) - *C; + assert(NC && "Couldn't constant fold a subtract!"); + return NC; + } + return 0; } -static inline Value *dyn_castNotInst(Value *V) { - return BinaryOperator::isNot(V) ? - BinaryOperator::getNotArgument(cast(V)) : 0; +static inline Value *dyn_castNotVal(Value *V) { + if (BinaryOperator::isNot(V)) + return BinaryOperator::getNotArgument(cast(V)); + + // Constants can be considered to be not'ed values... + if (ConstantIntegral *C = dyn_cast(V)) { + Constant *NC = *ConstantIntegral::getAllOnesValue(C->getType()) ^ *C; + assert(NC && "Couldn't constant fold an exclusive or!"); + return NC; + } + return 0; +} + +static bool isOnlyUse(Value *V) { + return V->use_size() == 1 || isa(V); } @@ -200,12 +220,13 @@ return ReplaceInstUsesWith(I, LHS); // -A + B --> B - A - if (Value *V = dyn_castNegInst(LHS)) + if (Value *V = dyn_castNegVal(LHS)) return BinaryOperator::create(Instruction::Sub, RHS, V); // A + -B --> A - B - if (Value *V = dyn_castNegInst(RHS)) - return BinaryOperator::create(Instruction::Sub, LHS, V); + if (!isa(RHS)) + if (Value *V = dyn_castNegVal(RHS)) + return BinaryOperator::create(Instruction::Sub, LHS, V); // X*C + X --> X * (C+1) if (dyn_castFoldableMul(LHS) == RHS) { @@ -232,15 +253,8 @@ if (Op0 == Op1) // sub X, X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - // If this is a subtract instruction with a constant RHS, convert it to an add - // instruction of a negative constant - // - if (Constant *Op2 = dyn_cast(Op1)) - if (Constant *RHS = *Constant::getNullValue(I.getType()) - *Op2) // 0 - RHS - return BinaryOperator::create(Instruction::Add, Op0, RHS, I.getName()); - // If this is a 'B = x-(-A)', change to B = x+A... - if (Value *V = dyn_castNegInst(Op1)) + if (Value *V = dyn_castNegVal(Op1)) return BinaryOperator::create(Instruction::Add, Op0, V); // Replace (-1 - A) with (~A)... @@ -424,11 +438,11 @@ if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); - Value *Op0NotVal = dyn_castNotInst(Op0); - Value *Op1NotVal = dyn_castNotInst(Op1); + Value *Op0NotVal = dyn_castNotVal(Op0); + Value *Op1NotVal = dyn_castNotVal(Op1); // (~A & ~B) == (~(A | B)) - Demorgan's Law - if (Op0->use_size() == 1 && Op1->use_size() == 1 && Op0NotVal && Op1NotVal) { + if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) { Instruction *Or = BinaryOperator::create(Instruction::Or, Op0NotVal, Op1NotVal,I.getName()+".demorgan", &I); @@ -456,12 +470,12 @@ if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op1); - if (Value *X = dyn_castNotInst(Op0)) // ~A | A == -1 + if (Value *X = dyn_castNotVal(Op0)) // ~A | A == -1 if (X == Op1) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); - if (Value *X = dyn_castNotInst(Op1)) // A | ~A == -1 + if (Value *X = dyn_castNotVal(Op1)) // A | ~A == -1 if (X == Op0) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); @@ -487,7 +501,7 @@ // Is this a "NOT" instruction? if (Op1C->isAllOnesValue()) { // xor (xor X, -1), -1 = not (not X) = X - if (Value *X = dyn_castNotInst(Op0)) + if (Value *X = dyn_castNotVal(Op0)) return ReplaceInstUsesWith(I, X); // xor (setcc A, B), true = not (setcc A, B) = setncc A, B @@ -498,12 +512,12 @@ } } - if (Value *X = dyn_castNotInst(Op0)) // ~A ^ A == -1 + if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1 if (X == Op1) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); - if (Value *X = dyn_castNotInst(Op1)) // A ^ ~A == -1 + if (Value *X = dyn_castNotVal(Op1)) // A ^ ~A == -1 if (X == Op0) return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); From lattner at cs.uiuc.edu Mon Mar 10 17:14:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 17:14:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/not.ll Message-ID: <200303102313.RAA16947@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: not.ll updated: 1.6 -> 1.7 --- Log message: Add test for demorgans law with constants Add test for other form of demorgans --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/not.ll diff -u llvm/test/Regression/Transforms/InstCombine/not.ll:1.6 llvm/test/Regression/Transforms/InstCombine/not.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/not.ll:1.6 Fri Aug 23 13:31:18 2002 +++ llvm/test/Regression/Transforms/InstCombine/not.ll Mon Mar 10 17:13:32 2003 @@ -29,3 +29,20 @@ %d = xor int %c, -1 ret int %d } + +; Test that demorgens law can work with constants +int %test4(int %A, int %B) { + %a = xor int %A, -1 + %c = and int %a, 5 ; 5 = ~c2 + %d = xor int %c, -1 + ret int %d +} + +; test the mirror of demorgans law... +int %test5(int %A, int %B) { + %a = xor int %A, -1 + %b = xor int %B, -1 + %c = or int %a, %b + %d = xor int %c, -1 + ret int %d +} From lattner at cs.uiuc.edu Mon Mar 10 17:15:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 17:15:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303102314.RAA16958@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.75 -> 1.76 --- Log message: Add new transformation: // (~A | ~B) == (~(A & B)) --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.75 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.76 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.75 Mon Mar 10 17:06:50 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 17:13:59 2003 @@ -446,6 +446,7 @@ Instruction *Or = BinaryOperator::create(Instruction::Or, Op0NotVal, Op1NotVal,I.getName()+".demorgan", &I); + WorkList.push_back(Or); return BinaryOperator::createNot(Or); } @@ -470,15 +471,25 @@ if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op1); - if (Value *X = dyn_castNotVal(Op0)) // ~A | A == -1 - if (X == Op1) - return ReplaceInstUsesWith(I, - ConstantIntegral::getAllOnesValue(I.getType())); - - if (Value *X = dyn_castNotVal(Op1)) // A | ~A == -1 - if (X == Op0) - return ReplaceInstUsesWith(I, - ConstantIntegral::getAllOnesValue(I.getType())); + Value *Op0NotVal = dyn_castNotVal(Op0); + Value *Op1NotVal = dyn_castNotVal(Op1); + + if (Op1 == Op0NotVal) // ~A | A == -1 + return ReplaceInstUsesWith(I, + ConstantIntegral::getAllOnesValue(I.getType())); + + if (Op0 == Op1NotVal) // A | ~A == -1 + return ReplaceInstUsesWith(I, + ConstantIntegral::getAllOnesValue(I.getType())); + + // (~A | ~B) == (~(A & B)) - Demorgan's Law + if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) { + Instruction *And = BinaryOperator::create(Instruction::And, Op0NotVal, + Op1NotVal,I.getName()+".demorgan", + &I); + WorkList.push_back(And); + return BinaryOperator::createNot(And); + } return Changed ? &I : 0; } From lattner at cs.uiuc.edu Mon Mar 10 17:24:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 17:24:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/sub.ll Message-ID: <200303102323.RAA17317@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: sub.ll updated: 1.8 -> 1.9 --- Log message: Add testcases for negated multiplies --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/sub.ll diff -u llvm/test/Regression/Transforms/InstCombine/sub.ll:1.8 llvm/test/Regression/Transforms/InstCombine/sub.ll:1.9 --- llvm/test/Regression/Transforms/InstCombine/sub.ll:1.8 Tue Feb 18 13:55:31 2003 +++ llvm/test/Regression/Transforms/InstCombine/sub.ll Mon Mar 10 17:22:50 2003 @@ -59,3 +59,16 @@ ret int %C } +int %test10(int %A, int %B) { ; -A*-B == A*B + %C = sub int 0, %A + %D = sub int 0, %B + %E = mul int %C, %D + ret int %E +} + +int %test10(int %A) { ; -A *c1 == A * -c1 + %C = sub int 0, %A + %E = mul int %C, 7 + ret int %E +} + From lattner at cs.uiuc.edu Mon Mar 10 17:24:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 17:24:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303102323.RAA17326@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.76 -> 1.77 --- Log message: Implement: -A*-B == A*B --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.76 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.77 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.76 Mon Mar 10 17:13:59 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 17:23:04 2003 @@ -342,6 +342,10 @@ } } + if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y + if (Value *Op1v = dyn_castNegVal(I.getOperand(1))) + return BinaryOperator::create(Instruction::Mul, Op0v, Op1v); + return Changed ? &I : 0; } From lattner at cs.uiuc.edu Mon Mar 10 17:54:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 17:54:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll and.ll or.ll Message-ID: <200303102353.RAA18058@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.6 -> 1.7 and.ll updated: 1.6 -> 1.7 or.ll updated: 1.10 -> 1.11 --- Log message: Add optimizations: - (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 - (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.6 llvm/test/Regression/Transforms/InstCombine/add.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.6 Tue Feb 18 13:55:31 2003 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Mon Mar 10 17:52:54 2003 @@ -51,3 +51,9 @@ ret int %C } +int %test8(int %A, int %B) { ; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 + %A1 = and int %A, 7 + %B1 = and int %B, 128 + %C = add int %A1, %B1 + ret int %C +} Index: llvm/test/Regression/Transforms/InstCombine/and.ll diff -u llvm/test/Regression/Transforms/InstCombine/and.ll:1.6 llvm/test/Regression/Transforms/InstCombine/and.ll:1.7 --- llvm/test/Regression/Transforms/InstCombine/and.ll:1.6 Mon Mar 10 16:43:56 2003 +++ llvm/test/Regression/Transforms/InstCombine/and.ll Mon Mar 10 17:52:54 2003 @@ -49,3 +49,4 @@ %C = and ubyte %B, 4 ret ubyte %C } + Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.10 llvm/test/Regression/Transforms/InstCombine/or.ll:1.11 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.10 Mon Mar 10 16:43:56 2003 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Mon Mar 10 17:52:54 2003 @@ -1,7 +1,7 @@ ; This test makes sure that these instructions are properly eliminated. ; -; RUN: if as < %s | opt -instcombine | dis | grep or\ +; RUN: if as < %s | opt -instcombine | dis | grep -v '%OROK = or' | grep or\ ; RUN: then exit 1 ; RUN: else exit 0 ; RUN: fi @@ -91,3 +91,11 @@ %C = xor ubyte %B, 17 ret ubyte %C } + +int %test16(int %A, int %B) { ; (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 + %A1 = and int %A, 7 + %B1 = and int %B, 128 + %OROK = xor int %A1, %B1 + ret int %OROK +} + From lattner at cs.uiuc.edu Mon Mar 10 18:12:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 18:12:04 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/InstCombine/add.ll or.ll Message-ID: <200303110011.SAA18518@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/InstCombine: add.ll updated: 1.7 -> 1.8 or.ll updated: 1.11 -> 1.12 --- Log message: Test limited reassociation --- Diffs of the changes: Index: llvm/test/Regression/Transforms/InstCombine/add.ll diff -u llvm/test/Regression/Transforms/InstCombine/add.ll:1.7 llvm/test/Regression/Transforms/InstCombine/add.ll:1.8 --- llvm/test/Regression/Transforms/InstCombine/add.ll:1.7 Mon Mar 10 17:52:54 2003 +++ llvm/test/Regression/Transforms/InstCombine/add.ll Mon Mar 10 18:10:59 2003 @@ -57,3 +57,4 @@ %C = add int %A1, %B1 ret int %C } + Index: llvm/test/Regression/Transforms/InstCombine/or.ll diff -u llvm/test/Regression/Transforms/InstCombine/or.ll:1.11 llvm/test/Regression/Transforms/InstCombine/or.ll:1.12 --- llvm/test/Regression/Transforms/InstCombine/or.ll:1.11 Mon Mar 10 17:52:54 2003 +++ llvm/test/Regression/Transforms/InstCombine/or.ll Mon Mar 10 18:10:59 2003 @@ -99,3 +99,9 @@ ret int %OROK } +ubyte %test17(ubyte %A, ubyte %B) { ; Test that (A|c1)|(B|c2) == (A|B)|(c1|c2) + %C = or ubyte %A, 1 + %D = or ubyte %B, 254 + %E = or ubyte %C, %D + ret ubyte %E +} From lattner at cs.uiuc.edu Mon Mar 10 18:13:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Mar 10 18:13:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200303110012.SAA18533@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: InstructionCombining.cpp updated: 1.77 -> 1.78 --- Log message: Add the following instcombine xforms: - Implement simple reassociation: (A|c1)|(B|c2) == (A|B)|(c1|c2) - (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 - (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 --- Diffs of the changes: Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.77 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.78 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.77 Mon Mar 10 17:23:04 2003 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 18:12:48 2003 @@ -104,6 +104,11 @@ I.replaceAllUsesWith(V); return &I; } + + // SimplifyCommutative - This performs a few simplifications for commutative + // operators... + bool SimplifyCommutative(BinaryOperator &I); + }; RegisterOpt X("instcombine", "Combine redundant instructions"); @@ -121,6 +126,12 @@ return isa(V) ? 0 : 1; } +// isOnlyUse - Return true if this instruction will be deleted if we stop using +// it. +static bool isOnlyUse(Value *V) { + return V->use_size() == 1 || isa(V); +} + // SimplifyCommutative - This performs a few simplifications for commutative // operators: // @@ -128,29 +139,43 @@ // left (most complex). This puts constants before unary operators before // binary operators. // -// 2. Handle the case of (op (op V, C1), C2), changing it to: -// (op V, (op C1, C2)) +// 2. Transform: (op (op V, C1), C2) ==> (op V, (op C1, C2)) +// 3. Transform: (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2)) // -static bool SimplifyCommutative(BinaryOperator &I) { +bool InstCombiner::SimplifyCommutative(BinaryOperator &I) { bool Changed = false; if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1))) Changed = !I.swapOperands(); if (!I.isAssociative()) return Changed; Instruction::BinaryOps Opcode = I.getOpcode(); - if (BinaryOperator *Op = dyn_cast(I.getOperand(0))) { - if (Op->getOpcode() == Opcode && isa(I.getOperand(1)) && - isa(Op->getOperand(1))) { - Instruction *New = BinaryOperator::create(I.getOpcode(), I.getOperand(1), - Op->getOperand(1)); - Constant *Folded = ConstantFoldInstruction(New); - delete New; - assert(Folded && "Couldn't constant fold commutative operand?"); - I.setOperand(0, Op->getOperand(0)); - I.setOperand(1, Folded); - return true; + if (BinaryOperator *Op = dyn_cast(I.getOperand(0))) + if (Op->getOpcode() == Opcode && isa(Op->getOperand(1))) { + if (isa(I.getOperand(1))) { + Constant *Folded = ConstantFoldBinaryInstruction(I.getOpcode(), + cast(I.getOperand(1)), cast(Op->getOperand(1))); + assert(Folded && "Couldn't constant fold commutative operand?"); + I.setOperand(0, Op->getOperand(0)); + I.setOperand(1, Folded); + return true; + } else if (BinaryOperator *Op1=dyn_cast(I.getOperand(1))) + if (Op1->getOpcode() == Opcode && isa(Op1->getOperand(1)) && + isOnlyUse(Op) && isOnlyUse(Op1)) { + Constant *C1 = cast(Op->getOperand(1)); + Constant *C2 = cast(Op1->getOperand(1)); + + // Fold (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2)) + Constant *Folded = ConstantFoldBinaryInstruction(I.getOpcode(),C1,C2); + assert(Folded && "Couldn't constant fold commutative operand?"); + Instruction *New = BinaryOperator::create(Opcode, Op->getOperand(0), + Op1->getOperand(0), + Op1->getName(), &I); + WorkList.push_back(New); + I.setOperand(0, New); + I.setOperand(1, Folded); + return true; + } } - } return Changed; } @@ -183,10 +208,30 @@ return 0; } -static bool isOnlyUse(Value *V) { - return V->use_size() == 1 || isa(V); +// dyn_castFoldableMul - If this value is a multiply that can be folded into +// other computations (because it has a constant operand), return the +// non-constant operand of the multiply. +// +static inline Value *dyn_castFoldableMul(Value *V) { + if (V->use_size() == 1 && V->getType()->isInteger()) + if (Instruction *I = dyn_cast(V)) + if (I->getOpcode() == Instruction::Mul) + if (isa(I->getOperand(1))) + return I->getOperand(0); + return 0; } +// dyn_castMaskingAnd - If this value is an And instruction masking a value with +// a constant, return the constant being anded with. +// +static inline Constant *dyn_castMaskingAnd(Value *V) { + if (Instruction *I = dyn_cast(V)) + if (I->getOpcode() == Instruction::And) + return dyn_cast(I->getOperand(1)); + + // If this is a constant, it acts just like we were masking with it. + return dyn_cast(V); +} // Log2 - Calculate the log base 2 for the specified value if it is exactly a // power of 2. @@ -201,16 +246,6 @@ return Count; } -static inline Value *dyn_castFoldableMul(Value *V) { - if (V->use_size() == 1 && V->getType()->isInteger()) - if (Instruction *I = dyn_cast(V)) - if (I->getOpcode() == Instruction::Mul) - if (isa(I->getOperand(1))) - return I->getOperand(0); - return 0; -} - - Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyCommutative(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); @@ -244,6 +279,12 @@ return BinaryOperator::create(Instruction::Mul, LHS, CP1); } + // (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0 + if (Constant *C1 = dyn_castMaskingAnd(LHS)) + if (Constant *C2 = dyn_castMaskingAnd(RHS)) + if ((*C1 & *C2)->isNullValue()) + return BinaryOperator::create(Instruction::Or, LHS, RHS); + return Changed ? &I : 0; } @@ -537,8 +578,6 @@ return ReplaceInstUsesWith(I, ConstantIntegral::getAllOnesValue(I.getType())); - - if (Instruction *Op1I = dyn_cast(Op1)) if (Op1I->getOpcode() == Instruction::Or) if (Op1I->getOperand(0) == Op0) { // B^(B|A) == (A|B)^B @@ -561,6 +600,12 @@ NotB); } } + + // (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1^C2 == 0 + if (Constant *C1 = dyn_castMaskingAnd(Op0)) + if (Constant *C2 = dyn_castMaskingAnd(Op1)) + if ((*C1 & *C2)->isNullValue()) + return BinaryOperator::create(Instruction::Or, Op0, Op1); return Changed ? &I : 0; } From lattner at apoc.cs.uiuc.edu Fri Mar 14 14:26:01 2003 From: lattner at apoc.cs.uiuc.edu (Chris Lattner) Date: Fri Mar 14 14:26:01 2003 Subject: [llvm-commits] CVS: llvm/Makefile.common Message-ID: <200303142025.h2EKPXG08371@apoc.cs.uiuc.edu> Changes in directory llvm: Makefile.common updated: 1.79 -> 1.80 --- Log message: Fix several bugs in the build system, including the use of the Debug version of Burg no matter what configuration is currently configured. --- Diffs of the changes: Index: llvm/Makefile.common diff -u llvm/Makefile.common:1.79 llvm/Makefile.common:1.80 --- llvm/Makefile.common:1.79 Wed Feb 19 16:12:20 2003 +++ llvm/Makefile.common Fri Mar 14 14:25:22 2003 @@ -104,18 +104,30 @@ PURIFY := $(PURIFY) -cache-dir="$(BUILD_ROOT_TOP)/../purifycache" -chain-length="30" -messages=all +ifdef ENABLE_PROFILING + ENABLE_OPTIMIZED = 1 + CONFIGURATION := Profile +else + ifdef ENABLE_OPTIMIZED + CONFIGURATION := Release + else + CONFIGURATION := Debug + endif +endif + # Shorthand for commonly accessed directories LIBDEBUG := $(BUILD_ROOT_TOP)/lib/Debug LIBRELEASE := $(BUILD_ROOT_TOP)/lib/Release LIBPROFILE := $(BUILD_ROOT_TOP)/lib/Profile +LIBCURRENT := $(BUILD_ROOT_TOP)/lib/$(CONFIGURATION) + TOOLDEBUG := $(BUILD_ROOT_TOP)/tools/Debug TOOLRELEASE := $(BUILD_ROOT_TOP)/tools/Release TOOLPROFILE := $(BUILD_ROOT_TOP)/tools/Profile +TOOLCURRENT := $(BUILD_ROOT_TOP)/tools/$(CONFIGURATION) # Verbosity levels -ifdef VERBOSE -VERB := -else +ifndef VERBOSE VERB := @ endif @@ -126,7 +138,7 @@ # Special tools used while building the LLVM tree. Burg is built as part of the # utils directory. # -BURG := $(TOOLDEBUG)/burg +BURG := $(TOOLCURRENT)/burg RunBurg := $(BURG) $(BURG_OPTS) @@ -134,16 +146,10 @@ # This automatically enables optimized builds. ifdef ENABLE_PROFILING PROFILE = -pg - ENABLE_OPTIMIZED = 1 -else - PROFILE = endif # By default, strip symbol information from executable -ifdef KEEP_SYMBOLS -STRIP = -STRIP_WARN_MSG = -else +ifndef KEEP_SYMBOLS STRIP = $(PLATFORMSTRIPOPTS) STRIP_WARN_MSG = "(without symbols) " endif @@ -265,43 +271,19 @@ LIBNAME_OBJP := $(LIBPROFILE)/$(LIBRARYNAME).o LIBNAME_OBJG := $(LIBDEBUG)/$(LIBRARYNAME).o +# dynamic target builds a shared object version of the library... +dynamic:: $(LIBCURRENT)/lib$(LIBRARYNAME).so -ifndef ENABLE_OPTIMIZED -BUILD_LIBNAME_G := $(LIBNAME_G) +# Does the library want a .o version built? ifndef DONT_BUILD_RELINKED -BUILD_LIBNAME_OBJG := $(LIBNAME_OBJG) -endif -ifdef BUILD_ARCHIVE -BUILD_LIBNAME_AG := $(LIBNAME_AG) -endif +all:: $(LIBCURRENT)/$(LIBRARYNAME).o endif -# If optimized builds are enabled... -ifdef ENABLE_OPTIMIZED - ifdef ENABLE_PROFILING - BUILD_LIBNAME_O := $(LIBNAME_P) - ifndef DONT_BUILD_RELINKED - BUILD_LIBNAME_OBJO := $(LIBNAME_OBJP) - endif - ifdef BUILD_ARCHIVE - BUILD_LIBNAME_AO := $(LIBNAME_AP) - endif - else - BUILD_LIBNAME_O := $(LIBNAME_O) - ifndef DONT_BUILD_RELINKED - BUILD_LIBNAME_OBJO := $(LIBNAME_OBJO) - endif - ifdef BUILD_ARCHIVE - BUILD_LIBNAME_AO := $(LIBNAME_AO) - endif - endif +# Does the library want an archive version built? +ifdef BUILD_ARCHIVE +all:: $(LIBCURRENT)/lib$(LIBRARYNAME).a endif -all:: $(BUILD_LIBNAME_AG) $(BUILD_LIBNAME_OBJG) # Debug -all:: $(BUILD_LIBNAME_AO) $(BUILD_LIBNAME_OBJO) # Release -all:: $(BUILD_LIBNAME_AP) $(BUILD_LIBNAME_OBJP) # Profile -dynamic:: $(BUILD_LIBNAME_G) $(BUILD_LIBNAME_O) $(BUILD_LIBNAME_P) # .so files - $(LIBNAME_O): $(ObjectsO) $(LibSubDirs) $(LIBRELEASE)/.dir @echo ======= Linking $(LIBRARYNAME) release library ======= $(VERB) $(MakeSOO) -o $@ $(ObjectsO) $(LibSubDirs) $(LibLinkOpts) @@ -368,16 +350,7 @@ TOOLEXENAME_G := $(BUILD_ROOT_TOP)/tools/Debug/$(TOOLNAME) TOOLEXENAME_O := $(BUILD_ROOT_TOP)/tools/Release/$(TOOLNAME) TOOLEXENAME_P := $(BUILD_ROOT_TOP)/tools/Profile/$(TOOLNAME) - -ifndef ENABLE_OPTIMIZED - TOOLEXENAMES := $(TOOLEXENAME_G) -else - ifdef ENABLE_PROFILING - TOOLEXENAMES := $(TOOLEXENAME_P) - else - TOOLEXENAMES := $(TOOLEXENAME_O) - endif -endif +TOOLEXENAMES := $(BUILD_ROOT_TOP)/tools/$(CONFIGURATION)/$(TOOLNAME) # USED_LIBS_OPTIONS - Compute the options line that add -llib1 -llib2, etc. USED_LIBS_OPTIONS := $(patsubst %.a.o, -l%, $(addsuffix .o, $(USEDLIBS)))