From: Chris Lattner Date: Tue, 21 Sep 2004 21:35:23 +0000 (+0000) Subject: Do not fold (X + C1 != C2) if there are other users of the add. Doing X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3d834bf2c37515c4fd3184aa883d2142d8b48d94;p=oota-llvm.git Do not fold (X + C1 != C2) if there are other users of the add. Doing this transformation used to take a loop like this: int Array[1000]; void test(int X) { int i; for (i = 0; i < 1000; ++i) Array[i] += X; } Compiled to LLVM is: no_exit: ; preds = %entry, %no_exit %indvar = phi uint [ 0, %entry ], [ %indvar.next, %no_exit ] ; [#uses=2] %tmp.4 = getelementptr [1000 x int]* %Array, int 0, uint %indvar ; [#uses=2] %tmp.7 = load int* %tmp.4 ; [#uses=1] %tmp.9 = add int %tmp.7, %X ; [#uses=1] store int %tmp.9, int* %tmp.4 *** %indvar.next = add uint %indvar, 1 ; [#uses=2] *** %exitcond = seteq uint %indvar.next, 1000 ; [#uses=1] br bool %exitcond, label %return, label %no_exit and turn it into a loop like this: no_exit: ; preds = %entry, %no_exit %indvar = phi uint [ 0, %entry ], [ %indvar.next, %no_exit ] ; [#uses=3] %tmp.4 = getelementptr [1000 x int]* %Array, int 0, uint %indvar ; [#uses=2] %tmp.7 = load int* %tmp.4 ; [#uses=1] %tmp.9 = add int %tmp.7, %X ; [#uses=1] store int %tmp.9, int* %tmp.4 *** %indvar.next = add uint %indvar, 1 ; [#uses=1] *** %exitcond = seteq uint %indvar, 999 ; [#uses=1] br bool %exitcond, label %return, label %no_exit Note that indvar.next and indvar can no longer be coallesced. In machine code terms, this patch changes this code: .LBBtest_1: # no_exit mov %EDX, OFFSET Array mov %ESI, %EAX add %ESI, DWORD PTR [%EDX + 4*%ECX] mov %EDX, OFFSET Array mov DWORD PTR [%EDX + 4*%ECX], %ESI mov %EDX, %ECX inc %EDX cmp %ECX, 999 mov %ECX, %EDX jne .LBBtest_1 # no_exit into this: .LBBtest_1: # no_exit mov %EDX, OFFSET Array mov %ESI, %EAX add %ESI, DWORD PTR [%EDX + 4*%ECX] mov %EDX, OFFSET Array mov DWORD PTR [%EDX + 4*%ECX], %ESI inc %ECX cmp %ECX, 1000 jne .LBBtest_1 # no_exit We need better instruction selection to get this: .LBBtest_1: # no_exit add DWORD PTR [Array + 4*%ECX], EAX inc %ECX cmp %ECX, 1000 jne .LBBtest_1 # no_exit ... but at least there is less register juggling git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16473 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index f3ffcf2e4bb..462824d1f8f 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1546,8 +1546,9 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { case Instruction::Add: // Replace ((add A, B) != C) with (A != C-B) if B & C are constants. if (ConstantInt *BOp1C = dyn_cast(BO->getOperand(1))) { - return new SetCondInst(I.getOpcode(), BO->getOperand(0), - ConstantExpr::getSub(CI, BOp1C)); + if (BO->hasOneUse()) + return new SetCondInst(I.getOpcode(), BO->getOperand(0), + ConstantExpr::getSub(CI, BOp1C)); } else if (CI->isNullValue()) { // Replace ((add A, B) != 0) with (A != -B) if A or B is // efficiently invertible, or if the add has just this one use.