[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