[llvm] [DAG] visitFREEZE - always allow freezing multiple operands (PR #145939)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 1 08:59:58 PDT 2025


================
@@ -278,16 +278,22 @@ define void @freeze_buildvector_single_maybe_poison_operand(ptr %origin, ptr %ds
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    vbroadcastss {{.*#+}} xmm0 = [42,42,42,42]
-; X86-NEXT:    vpinsrd $0, (%ecx), %xmm0, %xmm0
+; X86-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movl $42, %ecx
+; X86-NEXT:    vpinsrd $1, %ecx, %xmm0, %xmm0
+; X86-NEXT:    vpinsrd $2, %ecx, %xmm0, %xmm0
+; X86-NEXT:    vpinsrd $3, %ecx, %xmm0, %xmm0
----------------
RKSimon wrote:

It looks like we're getting screwed by lack of topological combine ordering:
```
Initial selection DAG: %bb.0 'freeze_buildvector_single_maybe_poison_operand:'
SelectionDAG has 30 nodes:
  t0: ch,glue = EntryToken
    t3: i32,ch = load<(load (s32) from %fixed-stack.1)> t0, FrameIndex:i32<-1>, undef:i32
  t7: i32,ch = load<(load (s32) from %ir.origin)> t0, t3, undef:i32
  t11: i64 = Constant<0>
  t14: i64 = Constant<1>
  t17: i64 = Constant<2>
  t20: i64 = Constant<3>
                  t9: i32 = and t7, Constant:i32<15>
                t12: v4i32 = insert_vector_elt poison:v4i32, t9, Constant:i32<0>
              t16: v4i32 = insert_vector_elt t12, Constant:i32<42>, Constant:i32<1>
            t19: v4i32 = insert_vector_elt t16, Constant:i32<42>, Constant:i32<2>
          t22: v4i32 = insert_vector_elt t19, Constant:i32<42>, Constant:i32<3>
        t23: v4i32 = freeze t22
        t25: v4i32 = BUILD_VECTOR Constant:i32<7>, Constant:i32<7>, Constant:i32<7>, Constant:i32<7>
      t26: v4i32 = and t23, t25
      t5: i32,ch = load<(load (s32) from %fixed-stack.0)> t0, FrameIndex:i32<-2>, undef:i32
    t27: ch = store<(store (s128) into %ir.dst)> t7:1, t26, t5, undef:i32
  t29: ch = X86ISD::RET_GLUE t27, TargetConstant:i32<0>
  
  -->
  
Type-legalized selection DAG: %bb.0 'freeze_buildvector_single_maybe_poison_operand:'
SelectionDAG has 27 nodes:
  t0: ch,glue = EntryToken
    t3: i32,ch = load<(load (s32) from %fixed-stack.1)> t0, FrameIndex:i32<-1>, undef:i32
  t7: i32,ch = load<(load (s32) from %ir.origin)> t0, t3, undef:i32
                t34: v4i32 = freeze poison:v4i32
                  t36: i32 = freeze t7
                t9: i32 = and t36, Constant:i32<15>
              t35: v4i32 = insert_vector_elt t34, t9, Constant:i32<0>
            t16: v4i32 = insert_vector_elt t35, Constant:i32<42>, Constant:i32<1>
          t19: v4i32 = insert_vector_elt t16, Constant:i32<42>, Constant:i32<2>
        t22: v4i32 = insert_vector_elt t19, Constant:i32<42>, Constant:i32<3>
        t25: v4i32 = BUILD_VECTOR Constant:i32<7>, Constant:i32<7>, Constant:i32<7>, Constant:i32<7>
      t26: v4i32 = and t22, t25
      t5: i32,ch = load<(load (s32) from %fixed-stack.0)> t0, FrameIndex:i32<-2>, undef:i32
    t27: ch = store<(store (s128) into %ir.dst)> t7:1, t26, t5, undef:i32
  t29: ch = X86ISD::RET_GLUE t27, TargetConstant:i32<0>
```
The freeze slowly gets pushed through the insert_vector_elt chain, so eventually its exposed again and should fold to build_vector but by that point, we don't visit the last insert_vector_elt anymore :( 

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


More information about the llvm-commits mailing list