[llvm] [InstCombine] Push freeze through non-recurrence PHIs (PR #157678)

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 6 09:21:12 PDT 2025


c-rhodes wrote:

Sharing some findings:
- There is no hang when disabling both `foldOpIntoPhi` and `foldFreezeIntoRecurrence`
  - this suggests these patterns are conflicting with `pushFreezeToPreventPoisonFromPropagating`
  - both patterns must be disabled, which suggests whatever the problem is exists in both
- ~13% of the debug output is poison values (from 5s testcase):
    ```
    520544 freeze <2 x double> poison
    267968 freeze <2 x i1> poison
    456696 freeze <4 x double> poison
- these comes from splats that are part of a wider vector reduction:
    ```
    1978 IC: pushFreezeToPreventPoisonFromPropagating ENTER  worklist=764 deferred=0 freeze=  %133 = freeze i1 %132
    1979 ADD DEFERRED:   %132 = icmp ne i4 %131, 0
    1980 ADD DEFERRED:   %131 = bitcast <4 x i1> %bin.rdx3030 to i4
    1981 ADD DEFERRED:   %bin.rdx3030 = or <4 x i1> %129, %bin.rdx3029
    1982 ADD DEFERRED:   %129 = or <4 x i1> %vec.phi3021, %125
    1983 ADD DEFERRED:   %vec.phi3021.fr = freeze <4 x i1> %vec.phi3021
    1984 ADD DEFERRED:   %125 = fcmp reassoc nsz arcp contract afn olt <4 x double> %wide.load3025, %broadcast.splat3015
    1985 ADD DEFERRED:   %wide.load3025.fr = freeze <4 x double> %wide.load3025
    1986 ADD DEFERRED:   %broadcast.splat3015 = shufflevector <4 x double> %broadcast.splatinsert3014, <4 x double> poison, <4 x i32> zeroinitializer
    1987 ADD DEFERRED:   %broadcast.splatinsert3014 = insertelement <4 x double> poison, double %108, i64 0
    1988 ADD DEFERRED:   %.fr = freeze <4 x double> poison
    1989 ADD DEFERRED:   %.fr1 = freeze double %108
    1990 ADD DEFERRED:   %.fr2 = freeze <4 x double> poison
    1991 ADD DEFERRED:   %bin.rdx3029 = or <4 x i1> %128, %bin.rdx3028
    1992 ADD DEFERRED:   %128 = or <4 x i1> %vec.phi3020, %124
    1993 ADD DEFERRED:   %vec.phi3020.fr = freeze <4 x i1> %vec.phi3020
    1994 ADD DEFERRED:   %124 = fcmp reassoc nsz arcp contract afn olt <4 x double> %wide.load3024, %broadcast.splat3015
    1995 ADD DEFERRED:   %wide.load3024.fr = freeze <4 x double> %wide.load3024
    1996 ADD DEFERRED:   %bin.rdx3028 = or <4 x i1> %127, %126
    1997 ADD DEFERRED:   %127 = or <4 x i1> %vec.phi3019, %123
    1998 ADD DEFERRED:   %vec.phi3019.fr = freeze <4 x i1> %vec.phi3019
    1999 ADD DEFERRED:   %123 = fcmp reassoc nsz arcp contract afn olt <4 x double> %wide.load3023, %broadcast.splat3015
    2000 ADD DEFERRED:   %wide.load3023.fr = freeze <4 x double> %wide.load3023
    2001 ADD DEFERRED:   %126 = or <4 x i1> %vec.phi3018, %122
    2002 ADD DEFERRED:   %vec.phi3018.fr = freeze <4 x i1> %vec.phi3018
    2003 ADD DEFERRED:   %122 = fcmp reassoc nsz arcp contract afn olt <4 x double> %wide.load3022, %broadcast.splat3015
    2004 ADD DEFERRED:   %wide.load3022.fr = freeze <4 x double> %wide.load3022
    2005 IC: Replacing   %133 = freeze i1 %132
    2006     with   %132 = icmp ne i4 %131, 0
    2007 IC: pushFreezeToPreventPoisonFromPropagating SUCCESS  worklist=764 deferred=26
- Some calls to `pushFreezeToPreventPoisonFromPropagating` cause the `Worklist` to increase significantly, looking at the debug output for the 5s case the worst one increases the `Worklist` by 260 instructions:
    ```
    4299905 IC: Visiting:   %385 = bitcast <2 x i1> %384 to i2
    4299906 IC: Visiting:   %386 = icmp ne i2 %385, 0
    4299907 IC: Visiting:   %384 = or <2 x i1> %broadcast.splat2525, %383
    4299908 IC: Visiting:   %387 = freeze i1 %386
    4299909 IC: pushFreezeToPreventPoisonFromPropagating ENTER  worklist=12 deferred=0 freeze=  %387 = freeze i1 %386
    ...
    4300170 IC: Replacing   %387 = freeze i1 %386
    4300171     with   %386 = icmp ne i2 %385, 0
    4300172 IC: pushFreezeToPreventPoisonFromPropagating SUCCESS  worklist=12 deferred=260
- I found reverting the change to `pushFreezeToPreventPoisonFromPropagating` in #154336 to emit the freezes in a more natural order fixes the hang:
```
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 6004feb1d885..51739e818d59 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -5041,7 +5047,7 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
       continue;

     // reverse() to emit freezes in a more natural order.
-    for (Use &Op : reverse(I->operands())) {
+    for (Use &Op : I->operands()) {
       Value *OpV = Op.get();
       if (isa<MetadataAsValue>(OpV) || isGuaranteedNotToBeUndefOrPoison(OpV))
         continue;
```
although I'm not sure why that's the case or if it's sensible.

https://github.com/llvm/llvm-project/pull/157678


More information about the llvm-commits mailing list