From: Chris Lattner Date: Sun, 9 Jan 2005 20:52:51 +0000 (+0000) Subject: Add some folds for == and != comparisons. This allows us to X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5cdcc58d51c792d329202bab97c34aefbc043b15;p=oota-llvm.git Add some folds for == and != comparisons. This allows us to codegen this loop in stepanov: no_exit.i: ; preds = %entry, %no_exit.i, %then.i, %_Z5checkd.exit %i.0.0 = phi int [ 0, %entry ], [ %i.0.0, %no_exit.i ], [ %inc.0, %_Z5checkd.exit ], [ %inc.012, %then.i ] ; [#uses=3] %indvar = phi uint [ %indvar.next, %no_exit.i ], [ 0, %entry ], [ 0, %then.i ], [ 0, %_Z5checkd.exit ] ; [#uses=3] %result_addr.i.0 = phi double [ %tmp.4.i.i, %no_exit.i ], [ 0.000000e+00, %entry ], [ 0.000000e+00, %then.i ], [ 0.000000e+00, %_Z5checkd.exit ] ; [#uses=1] %first_addr.0.i.2.rec = cast uint %indvar to int ; [#uses=1] %first_addr.0.i.2 = getelementptr [2000 x double]* %data, int 0, uint %indvar ; [#uses=1] %inc.i.rec = add int %first_addr.0.i.2.rec, 1 ; [#uses=1] %inc.i = getelementptr [2000 x double]* %data, int 0, int %inc.i.rec ; [#uses=1] %tmp.3.i.i = load double* %first_addr.0.i.2 ; [#uses=1] %tmp.4.i.i = add double %result_addr.i.0, %tmp.3.i.i ; [#uses=2] %tmp.2.i = seteq double* %inc.i, getelementptr ([2000 x double]* %data, int 0, int 2000) ; [#uses=1] %indvar.next = add uint %indvar, 1 ; [#uses=1] br bool %tmp.2.i, label %_Z10accumulateIPddET0_T_S2_S1_.exit, label %no_exit.i To this: .LBB_Z4testIPddEvT_S1_T0__1: # no_exit.i fldl data(,%eax,8) fldl 16(%esp) faddp %st(1) fstpl 16(%esp) incl %eax movl %eax, %ecx shll $3, %ecx cmpl $16000, %ecx #FP_REG_KILL jne .LBB_Z4testIPddEvT_S1_T0__1 # no_exit.i instead of this: .LBB_Z4testIPddEvT_S1_T0__1: # no_exit.i fldl data(,%eax,8) fldl 16(%esp) faddp %st(1) fstpl 16(%esp) incl %eax leal data(,%eax,8), %ecx leal data+16000, %edx cmpl %edx, %ecx #FP_REG_KILL jne .LBB_Z4testIPddEvT_S1_T0__1 # no_exit.i git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19425 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 9c583049667..f3c18d37d3d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -22,6 +22,47 @@ #include using namespace llvm; +static bool isCommutativeBinOp(unsigned Opcode) { + switch (Opcode) { + case ISD::ADD: + case ISD::MUL: + case ISD::AND: + case ISD::OR: + case ISD::XOR: return true; + default: return false; // FIXME: Need commutative info for user ops! + } +} + +static bool isAssociativeBinOp(unsigned Opcode) { + switch (Opcode) { + case ISD::ADD: + case ISD::MUL: + case ISD::AND: + case ISD::OR: + case ISD::XOR: return true; + default: return false; // FIXME: Need associative info for user ops! + } +} + +static unsigned ExactLog2(uint64_t Val) { + unsigned Count = 0; + while (Val != 1) { + Val >>= 1; + ++Count; + } + return Count; +} + +// isInvertibleForFree - Return true if there is no cost to emitting the logical +// inverse of this node. +static bool isInvertibleForFree(SDOperand N) { + if (isa(N.Val)) return true; + if (isa(N.Val) && N.Val->hasOneUse()) + return true; + return false; +} + + /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X) /// when given the operation for (X op Y). ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) { @@ -357,6 +398,23 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1, Cond = UOF == 0 ? ISD::SETUO : ISD::SETO; } + // Simplify (X+Y) == (X+Z) --> Y == Z + if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && + N1.getOpcode() == N2.getOpcode() && MVT::isInteger(N1.getValueType())) + if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB) { + if (N1.getOperand(0) == N2.getOperand(0)) + return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1)); + if (N1.getOperand(1) == N2.getOperand(1)) + return getSetCC(Cond, N1.getOperand(0), N2.getOperand(0)); + if (isCommutativeBinOp(N1.getOpcode())) { + // If X op Y == Y op X, try other combinations. + if (N1.getOperand(0) == N2.getOperand(1)) + return getSetCC(Cond, N1.getOperand(1), N2.getOperand(0)); + if (N1.getOperand(1) == N2.getOperand(0)) + return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1)); + } + } + SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)]; if (N) return SDOperand(N, 0); @@ -449,47 +507,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, return SDOperand(N, 0); } -static bool isCommutativeBinOp(unsigned Opcode) { - switch (Opcode) { - case ISD::ADD: - case ISD::MUL: - case ISD::AND: - case ISD::OR: - case ISD::XOR: return true; - default: return false; // FIXME: Need commutative info for user ops! - } -} - -static bool isAssociativeBinOp(unsigned Opcode) { - switch (Opcode) { - case ISD::ADD: - case ISD::MUL: - case ISD::AND: - case ISD::OR: - case ISD::XOR: return true; - default: return false; // FIXME: Need associative info for user ops! - } -} - -static unsigned ExactLog2(uint64_t Val) { - unsigned Count = 0; - while (Val != 1) { - Val >>= 1; - ++Count; - } - return Count; -} - -// isInvertibleForFree - Return true if there is no cost to emitting the logical -// inverse of this node. -static bool isInvertibleForFree(SDOperand N) { - if (isa(N.Val)) return true; - if (isa(N.Val) && N.Val->hasOneUse()) - return true; - return false; -} - - SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N1, SDOperand N2) { ConstantSDNode *N1C = dyn_cast(N1.Val);