[llvm] [SCEV] Add special handling for phi when BranchInst's edge doesn't dominate use in phi (PR #163146)

Wenju He via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 26 22:55:54 PDT 2025


wenju-he wrote:

> Actually, I'm not understanding the pattern. Can you write it in Alive2? I got as far as the following (https://alive2.llvm.org/ce/z/7WAcTS):
> 
> ```
> define i32 @src(i32 %a, i1 %p) {
> entry:
>   %b = and i32 %a, 31
>   %c = icmp eq i32 %b, 0
>   br i1 %c, label %cmp_true, label %cmp_false
> 
> cmp_false:
>   br i1 %p, label %cmp_true, label %merge
> 
> cmp_true:
>   br label %merge
> 
> merge:
>   %d = phi i32 [32, %cmp_true], [%b, %cmp_false]
>   ret i32 %d
> }
> 
> define i32 @tgt(i32 %a, i1 %p) {
>   %b = and i32 %a, 31
>   %add = add i32 %a, 1
>   %max = call i32 @llvm.umax.i32(i32 %add, i32 1)
>   ret i32 %max
> }
> ```

It would be https://alive2.llvm.org/ce/z/vLckwS and `tgt` is
```
define i32 @tgt(i32 %a, i1 %p) {
  %b = and i32 %a, 31
  %c = icmp eq i32 %b, 0
  %cp = or i1 %c, %p
  %d = select i1 %cp, i32 32, i32 %b
  ret i32 %d
}
```

> Would it make sense to add an InstCombine or something like that for this pattern?

Thanks for the suggestion. CFG in above `tgt` is much simpler, however, our original code (shown below) has a large number of instructions in basic block `cmp_false`. It doesn't looks profitable to flatten the cfg. The control flow is uniform since `%7` has the same value for all work-items in an OpenCL sub group, so there is minimal penalty compared to a divergent branch. Typically `%7` is true.
```
define i32 @_Z27__spirv_BuiltInSubgroupSizev() {
  %1 = tail call i32 @llvm.xxxx.local.size.x()
  %2 = tail call i32 @llvm.xxxx.local.size.y()
  %3 = mul i32 %2, %1
  %4 = tail call i32 @llvm.xxxx.local.size.z()
  %5 = mul i32 %3, %4
  %6 = and i32 31, %5
  %7 = icmp eq i32 %6, 0
  br i1 %7, label %35, label %8

8:                                                ; preds = %0
  tail call void @llvm.assume(i1 true)
  %9 = tail call i32 @llvm.xxxx.local.id.z()
  %10 = zext nneg i32 %9 to i64
  %11 = tail call i32 @llvm.xxxx.local.size.y()
  %12 = zext nneg i32 %11 to i64
  %13 = mul i32 %11, %9
  tail call void @llvm.assume(i1 true)
  %14 = tail call i32 @llvm.xxxx.local.id.y()
  %15 = zext nneg i32 %14 to i64
  %16 = add i32 %13, %14
  %17 = tail call i32 @llvm.xxxx.local.size.x()
  %18 = zext nneg i32 %17 to i64
  %19 = mul i32 %16, %17
  tail call void @llvm.assume(i1 true)
  %20 = tail call i32 @llvm.xxxx.local.id.x()
  %21 = zext nneg i32 %20 to i64
  %22 = add i32 %19, %20
  %23 = zext i32 %22 to i64
  %24 = udiv i32 %22, 32
  %25 = tail call i32 @llvm.xxxx.local.size.x()
  %26 = tail call i32 @llvm.xxxx.local.size.y()
  %27 = mul i32 %26, %25
  %28 = tail call i32 @llvm.xxxx.local.size.z()
  %29 = mul i32 %27, %28
  %30 = add i32 32, %29
  %31 = add i32 %30, -1
  %32 = udiv i32 %31, 32
  %33 = add i32 %32, -1
  %34 = icmp ult i32 %24, %33
  br i1 %34, label %35, label %_Z24__clc_get_sub_group_sizev.exit

35:                                               ; preds = %8, %0
  br label %_Z24__clc_get_sub_group_sizev.exit

_Z24__clc_get_sub_group_sizev.exit:               ; preds = %35, %8
  %36 = phi i32 [ 32, %35 ], [ %6, %8 ]
  ret i32 %36
}
```

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


More information about the llvm-commits mailing list