[llvm] 92a9b1c - [InstCombine] Don't push operation across loop phi

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 13 01:49:01 PDT 2022


Author: Nikita Popov
Date: 2022-06-13T10:48:09+02:00
New Revision: 92a9b1c9184cbb382257ca8bf3e079ab8f20b038

URL: https://github.com/llvm/llvm-project/commit/92a9b1c9184cbb382257ca8bf3e079ab8f20b038
DIFF: https://github.com/llvm/llvm-project/commit/92a9b1c9184cbb382257ca8bf3e079ab8f20b038.diff

LOG: [InstCombine] Don't push operation across loop phi

When pushing an operation across a phi node, we should avoid doing
so across a loop backedge. This is generally non-profitable, because
it does not reduce the number of times the operation is executed,
and could lead to an infinite combine loop.

The code was already guarding against this, but using an
insufficiently strong condition, which did not cover the case where
the operation was originally outside the loop (in which case the
transform moves the operation from outside the loop into the loop,
which is particularly undesirable).

Differential Revision: https://reviews.llvm.org/D127499

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/test/Transforms/InstCombine/cast_phi.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 6bee548660442..59b9b8f193be6 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1177,10 +1177,11 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
       if (cast<Instruction>(InVal)->getParent() == NonConstBB)
         return nullptr;
 
-    // If the incoming non-constant value is in I's block, we will remove one
-    // instruction, but insert another equivalent one, leading to infinite
-    // instcombine.
-    if (isPotentiallyReachable(I.getParent(), NonConstBB, nullptr, &DT, LI))
+    // If the incoming non-constant value is reachable from the phis block,
+    // we'll push the operation across a loop backedge. This could result in
+    // an infinite combine loop, and is generally non-profitable (especially
+    // if the operation was originally outside the loop).
+    if (isPotentiallyReachable(PN->getParent(), NonConstBB, nullptr, &DT, LI))
       return nullptr;
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/cast_phi.ll b/llvm/test/Transforms/InstCombine/cast_phi.ll
index 84aa2b58dc947..d47526e088386 100644
--- a/llvm/test/Transforms/InstCombine/cast_phi.ll
+++ b/llvm/test/Transforms/InstCombine/cast_phi.ll
@@ -320,15 +320,15 @@ define i8 @trunc_in_loop_exit_block() {
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
-; CHECK-NEXT:    [[PHI:%.*]] = phi i8 [ 1, [[ENTRY]] ], [ [[PHI_CAST:%.*]], [[LOOP_LATCH]] ]
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[IV]], 100
 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    [[PHI_CAST]] = trunc i32 [[IV_NEXT]] to i8
 ; CHECK-NEXT:    br label [[LOOP]]
 ; CHECK:       exit:
-; CHECK-NEXT:    ret i8 [[PHI]]
+; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8
+; CHECK-NEXT:    ret i8 [[TRUNC]]
 ;
 entry:
   br label %loop
@@ -353,16 +353,16 @@ define i32 @zext_in_loop_and_exit_block(i8 %step, i32 %end) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[PHI_CAST:%.*]], [[LOOP_LATCH:%.*]] ]
-; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[IV]], [[END:%.*]]
+; CHECK-NEXT:    [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[IV_EXT:%.*]] = zext i8 [[IV]] to i32
+; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[IV_EXT]], [[END:%.*]]
 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
-; CHECK-NEXT:    [[IV_TR:%.*]] = trunc i32 [[IV]] to i8
-; CHECK-NEXT:    [[IV_NEXT_NARROW:%.*]] = add i8 [[IV_TR]], [[STEP:%.*]]
-; CHECK-NEXT:    [[PHI_CAST]] = zext i8 [[IV_NEXT_NARROW]] to i32
+; CHECK-NEXT:    [[IV_NEXT]] = add i8 [[IV]], [[STEP:%.*]]
 ; CHECK-NEXT:    br label [[LOOP]]
 ; CHECK:       exit:
-; CHECK-NEXT:    ret i32 [[IV]]
+; CHECK-NEXT:    [[EXT:%.*]] = zext i8 [[IV]] to i32
+; CHECK-NEXT:    ret i32 [[EXT]]
 ;
 entry:
   br label %loop


        


More information about the llvm-commits mailing list