From: Dan Gohman Date: Mon, 26 Nov 2007 23:46:11 +0000 (+0000) Subject: Don't lower srem/urem X%C to X-X/C*C unless the division is actually X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=77003040b21816725dc1ca3a55111044d36ac21f;p=oota-llvm.git Don't lower srem/urem X%C to X-X/C*C unless the division is actually optimized. This avoids creating illegal divisions when the combiner is running after legalize; this fixes PR1815. Also, it produces better code in the included testcase by avoiding the subtract and multiply when the division isn't optimized. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44341 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8f6800a2c6b..3be1fdd0c7f 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1306,15 +1306,17 @@ SDOperand DAGCombiner::visitSREM(SDNode *N) { DAG.MaskedValueIsZero(N0, SignBit)) return DAG.getNode(ISD::UREM, VT, N0, N1); - // Unconditionally lower X%C -> X-X/C*C. This allows the X/C logic to hack on - // the remainder operation. + // If X/C can be simplified by the division-by-constant logic, lower + // X%C to the equivalent of X-X/C*C. if (N1C && !N1C->isNullValue()) { SDOperand Div = DAG.getNode(ISD::SDIV, VT, N0, N1); - SDOperand Mul = DAG.getNode(ISD::MUL, VT, Div, N1); - SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); - AddToWorkList(Div.Val); - AddToWorkList(Mul.Val); - return Sub; + SDOperand OptimizedDiv = combine(Div.Val); + if (OptimizedDiv.Val && OptimizedDiv.Val != Div.Val) { + SDOperand Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1); + SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); + AddToWorkList(Mul.Val); + return Sub; + } } // undef % X -> 0 @@ -1351,15 +1353,17 @@ SDOperand DAGCombiner::visitUREM(SDNode *N) { } } - // Unconditionally lower X%C -> X-X/C*C. This allows the X/C logic to hack on - // the remainder operation. + // If X/C can be simplified by the division-by-constant logic, lower + // X%C to the equivalent of X-X/C*C. if (N1C && !N1C->isNullValue()) { SDOperand Div = DAG.getNode(ISD::UDIV, VT, N0, N1); - SDOperand Mul = DAG.getNode(ISD::MUL, VT, Div, N1); - SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); - AddToWorkList(Div.Val); - AddToWorkList(Mul.Val); - return Sub; + SDOperand OptimizedDiv = combine(Div.Val); + if (OptimizedDiv.Val && OptimizedDiv.Val != Div.Val) { + SDOperand Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1); + SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul); + AddToWorkList(Mul.Val); + return Sub; + } } // undef % X -> 0 diff --git a/test/CodeGen/X86/urem-i8-constant.ll b/test/CodeGen/X86/urem-i8-constant.ll new file mode 100644 index 00000000000..8a433334f62 --- /dev/null +++ b/test/CodeGen/X86/urem-i8-constant.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep mul + +define i8 @foo(i8 %tmp325) { + %t546 = urem i8 %tmp325, 37 + ret i8 %t546 +}