[llvm] [CVP] Guard against undef in common phi value transform (#198836) (PR #203238)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 03:58:37 PDT 2026


lijinpei-amd wrote:

> ⚠️ undef deprecator found issues in your code. ⚠️
> 
> You can test this locally with the following command:
> ```shell
> git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef([^a-zA-Z0-9_-]|$)|UndefValue::get)' 'HEAD~1' HEAD llvm/include/llvm/Analysis/LazyValueInfo.h llvm/include/llvm/Analysis/ValueLattice.h llvm/lib/Analysis/LazyValueInfo.cpp llvm/lib/Analysis/ValueLattice.cpp llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp llvm/lib/Transforms/Utils/SCCPSolver.cpp llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll llvm/unittests/Analysis/ValueLatticeTest.cpp
> ```
> 
> The following files introduce new uses of undef:
> 
> * llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll
> 
> [Undef](https://llvm.org/docs/LangRef.html#undefined-values) is now deprecated and should only be used in the rare cases where no replacement is possible. For example, a load of uninitialized memory yields `undef`. You should use `poison` values for placeholders instead.
> 
> In tests, avoid using `undef` and having tests that trigger undefined behavior. If you need an operand with some unimportant value, you can add a new argument to the function and use that instead.
> 
> For example, this is considered a bad practice:
> 
> ```llvm
> define void @fn() {
>   ...
>   br i1 undef, ...
> }
> ```
> 
> Please use the following instead:
> 
> ```llvm
> define void @fn(i1 %cond) {
>   ...
>   br i1 %cond, ...
> }
> ```
> 
> Please refer to the [Undefined Behavior Manual](https://llvm.org/docs/UndefinedBehavior.html) for more information.

The undef is due to uninitialized  c13 on some path, and first made explicit by SROA.
```
; *** IR Dump After SimplifyCFGPass on f9 ***
; Function Attrs: nounwind uwtable
define dso_local void @f9(i64 noundef %a0) #0 {
entry:
  %a0.addr = alloca i64, align 8
  %c13 = alloca i8, align 1
  store i64 %a0, ptr %a0.addr, align 8, !tbaa !8
  call void @llvm.lifetime.start.p0(ptr %c13) #3
  br label %lbl_entry

lbl_entry:                                        ; preds = %lbl_sw8, %entry
  %0 = load i64, ptr %a0.addr, align 8, !tbaa !8
  %rem = urem i64 %0, -63507613781690
  store i64 %rem, ptr @g3, align 8, !tbaa !8
  store i64 0, ptr @g8, align 8, !tbaa !8
  %1 = load i64, ptr @g3, align 8, !tbaa !8
  switch i64 %1, label %sw.default [
    i64 -40078572536881, label %lbl_sw7
    i64 3, label %lbl_sw8
  ]

sw.default:                                       ; preds = %lbl_entry
  store i8 0, ptr %c13, align 1, !tbaa !10
  br label %lbl_br16

lbl_sw7:                                          ; preds = %lbl_entry
  %2 = load i8, ptr @g29, align 1, !tbaa !10, !range !12, !noundef !13
  %loadedv = trunc i8 %2 to i1
  br i1 %loadedv, label %lbl_br16, label %lbl_sw8

lbl_sw8:                                          ; preds = %lbl_sw7, %lbl_entry
  %3 = load i64, ptr @g3, align 8, !tbaa !8
  %cmp = icmp eq i64 0, %3
  %storedv = zext i1 %cmp to i8
  store i8 %storedv, ptr %c13, align 1, !tbaa !10
  call void @f10()
  br label %lbl_entry

lbl_br16:                                         ; preds = %lbl_sw7, %sw.default
  %4 = load i8, ptr %c13, align 1, !tbaa !10, !range !12, !noundef !13
  %loadedv2 = trunc i8 %4 to i1
  %5 = xor i1 %loadedv2, true
  call void @llvm.assume(i1 %5)
  call void @llvm.lifetime.end.p0(ptr %c13) #3
  ret void
}
; *** IR Dump After SROAPass on f9 ***
; Function Attrs: nounwind uwtable
define dso_local void @f9(i64 noundef %a0) #0 {
entry:
  br label %lbl_entry

lbl_entry:                                        ; preds = %lbl_sw8, %entry
  %c13.0 = phi i8 [ undef, %entry ], [ %storedv, %lbl_sw8 ]
  %rem = urem i64 %a0, -63507613781690
  store i64 %rem, ptr @g3, align 8, !tbaa !8
  store i64 0, ptr @g8, align 8, !tbaa !8
  %0 = load i64, ptr @g3, align 8, !tbaa !8
  switch i64 %0, label %sw.default [
    i64 -40078572536881, label %lbl_sw7
    i64 3, label %lbl_sw8
  ]

sw.default:                                       ; preds = %lbl_entry
  br label %lbl_br16

lbl_sw7:                                          ; preds = %lbl_entry
  %1 = load i8, ptr @g29, align 1, !tbaa !10, !range !12, !noundef !13
  %loadedv = trunc i8 %1 to i1
  br i1 %loadedv, label %lbl_br16, label %lbl_sw8

lbl_sw8:                                          ; preds = %lbl_sw7, %lbl_entry
  %2 = load i64, ptr @g3, align 8, !tbaa !8
  %cmp = icmp eq i64 0, %2
  %storedv = zext i1 %cmp to i8
  call void @f10()
  br label %lbl_entry

lbl_br16:                                         ; preds = %lbl_sw7, %sw.default
  %c13.1 = phi i8 [ 0, %sw.default ], [ %c13.0, %lbl_sw7 ]
  %loadedv2 = trunc i8 %c13.1 to i1
  %3 = xor i1 %loadedv2, true
  call void @llvm.assume(i1 %3)
  ret void
}

```
I can make some testcase with -pass=sroa,correlated-propagation, and looks like no explicit undef in initial ir, but I don't know if the make things simpler.

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


More information about the llvm-commits mailing list