Test: Transforms/JumpThreading/select.ll Summary: the optimized code has a new jump on `%phitmp`, which is UB if either %y or %z are poison. The original code doesn't have any jump depending on either of these values. A correct version requires introducing of freeze. define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) { %entry: %add3 = add nsw i32 %j, 2 %cmp.i = icmp slt i32 %u, %v br i1 %cmp.i, label %.exit, label %cond.false.i %cond.false.i: %cmp4.i = icmp sgt i32 %u, %v br i1 %cmp4.i, label %.exit, label %cond.false.6.i %cond.false.6.i: %cmp8.i = icmp slt i32 %w, %x br i1 %cmp8.i, label %.exit, label %cond.false.10.i %cond.false.10.i: %cmp13.i = icmp sgt i32 %w, %x br i1 %cmp13.i, label %.exit, label %cond.false.15.i %cond.false.15.i: %phitmp = icmp sge i32 %y, %z br label %.exit %.exit: %cond23.i = phi i1 [ 0, %entry ], [ 1, %cond.false.i ], [ 0, %cond.false.6.i ], [ %phitmp, %cond.false.15.i ], [ 1, %cond.false.10.i ] %j.add3 = select i1 %cond23.i, i32 %j, i32 %add3 ret i32 %j.add3 } => define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) { %entry: %add3 = add nsw i32 %j, 2 %cmp.i = icmp slt i32 %u, %v br i1 %cmp.i, label %.exit.thread3, label %cond.false.i %cond.false.i: %cmp4.i = icmp sgt i32 %u, %v br i1 %cmp4.i, label %.exit.thread, label %cond.false.6.i %cond.false.6.i: %cmp8.i = icmp slt i32 %w, %x br i1 %cmp8.i, label %.exit.thread3, label %cond.false.10.i %cond.false.10.i: %cmp13.i = icmp sgt i32 %w, %x br i1 %cmp13.i, label %.exit.thread, label %.exit %.exit: %phitmp = icmp sge i32 %y, %z br i1 %phitmp, label %.exit.thread, label %.exit.thread3 %.exit.thread: br label %.exit.thread3 %.exit.thread3: %0 = phi i32 [ %j, %.exit.thread ], [ %add3, %.exit ], [ %add3, %entry ], [ %add3, %cond.false.6.i ] ret i32 %0 } Transformation doesn't verify! ERROR: Source is more defined than target Example: i32 %u = #x2ba5afc9 (732278729) i32 %v = #x2ba5afc9 (732278729) i32 %w = #x400000c1 (1073742017) i32 %x = #x400000c1 (1073742017) i32 %y = poison i32 %z = poison i32 %j = poison Source: i32 %add3 = poison i1 %cmp.i = #x0 (0) i1 %cmp4.i = #x0 (0) i1 %cmp8.i = #x0 (0) i1 %cmp13.i = #x0 (0) i1 %phitmp = poison i1 %cond23.i = poison i32 %j.add3 = poison Target: i32 %add3 = poison i1 %cmp.i = #x0 (0) i1 %cmp4.i = #x0 (0) i1 %cmp8.i = #x0 (0) i1 %cmp13.i = #x0 (0) i1 %phitmp = poison i32 %0 = poison
To fix this, LazyValueInfo should be able to look into freeze to minimize performance degradation. I'll take a look.
Relevant commit: https://github.com/llvm/llvm-project/commit/f9471b001089c744050c7a9cff39ebda2ff69011