[llvm] [DAG] SelectionDAG::canCreateUndefOrPoison - Mark AVGFLOORS and AVGCEILS as safe (PR #148191)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 11 07:55:01 PDT 2025


aabhinavg1 wrote:

Hi @RKSimon 

here is the test could you please look in to it if i have not missed anything

```cpp
; RUN: opt -passes=instcombine -S < %s | FileCheck %s

; === Signed Floor Average (AVGFLOORS) ===

define i8 @avg_signed_floor_freeze_before(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_signed_floor_freeze_before(
; CHECK: freeze i8
entry:
  %fa = freeze i8 %a
  %fb = freeze i8 %b
  %a32 = sext i8 %fa to i32
  %b32 = sext i8 %fb to i32
  %and = and i32 %a32, %b32
  %xor = xor i32 %a32, %b32
  %shr = ashr i32 %xor, 1
  %sum = add i32 %and, %shr
  %res = trunc i32 %sum to i8
  ret i8 %res
}

define i8 @avg_signed_floor_freeze_after(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_signed_floor_freeze_after(
; CHECK: freeze i8
entry:
  %a32 = sext i8 %a to i32
  %b32 = sext i8 %b to i32
  %and = and i32 %a32, %b32
  %xor = xor i32 %a32, %b32
  %shr = ashr i32 %xor, 1
  %sum = add i32 %and, %shr
  %res = trunc i32 %sum to i8
  %fr = freeze i8 %res
  ret i8 %fr
}

; === Signed Ceil Average (AVGCEILS) ===

define i8 @avg_signed_ceil_freeze_before(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_signed_ceil_freeze_before(
; CHECK: freeze i8
entry:
  %fa = freeze i8 %a
  %fb = freeze i8 %b
  %a32 = sext i8 %fa to i32
  %b32 = sext i8 %fb to i32
  %add = add i32 %a32, %b32
  %add1 = add i32 %add, 1
  %shr = ashr i32 %add1, 1
  %res = trunc i32 %shr to i8
  ret i8 %res
}

define i8 @avg_signed_ceil_freeze_after(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_signed_ceil_freeze_after(
; CHECK: freeze i8
entry:
  %a32 = sext i8 %a to i32
  %b32 = sext i8 %b to i32
  %add = add i32 %a32, %b32
  %add1 = add i32 %add, 1
  %shr = ashr i32 %add1, 1
  %res = trunc i32 %shr to i8
  %fr = freeze i8 %res
  ret i8 %fr
}

; === Unsigned Floor Average (AVGFLOORU) ===

define i8 @avg_unsigned_floor_freeze_before(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_unsigned_floor_freeze_before(
; CHECK: freeze i8
entry:
  %fa = freeze i8 %a
  %fb = freeze i8 %b
  %a32 = zext i8 %fa to i32
  %b32 = zext i8 %fb to i32
  %and = and i32 %a32, %b32
  %xor = xor i32 %a32, %b32
  %shr = lshr i32 %xor, 1
  %sum = add i32 %and, %shr
  %res = trunc i32 %sum to i8
  ret i8 %res
}

define i8 @avg_unsigned_floor_freeze_after(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_unsigned_floor_freeze_after(
; CHECK: freeze i8
entry:
  %a32 = zext i8 %a to i32
  %b32 = zext i8 %b to i32
  %and = and i32 %a32, %b32
  %xor = xor i32 %a32, %b32
  %shr = lshr i32 %xor, 1
  %sum = add i32 %and, %shr
  %res = trunc i32 %sum to i8
  %fr = freeze i8 %res
  ret i8 %fr
}

; === Unsigned Ceil Average (AVGCEILU) ===

define i8 @avg_unsigned_ceil_freeze_before(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_unsigned_ceil_freeze_before(
; CHECK: freeze i8
entry:
  %fa = freeze i8 %a
  %fb = freeze i8 %b
  %a32 = zext i8 %fa to i32
  %b32 = zext i8 %fb to i32
  %add = add i32 %a32, %b32
  %add1 = add i32 %add, 1
  %shr = lshr i32 %add1, 1
  %res = trunc i32 %shr to i8
  ret i8 %res
}

define i8 @avg_unsigned_ceil_freeze_after(i8 %a, i8 %b) {
; CHECK-LABEL: @avg_unsigned_ceil_freeze_after(
; CHECK: freeze i8
entry:
  %a32 = zext i8 %a to i32
  %b32 = zext i8 %b to i32
  %add = add i32 %a32, %b32
  %add1 = add i32 %add, 1
  %shr = lshr i32 %add1, 1
  %res = trunc i32 %shr to i8
  %fr = freeze i8 %res
  ret i8 %fr
}

```


I’ve added `avg-poison-safety.ll` with test coverage for all four ops:
- AVGFLOORS (signed floor)
- AVGCEILS (signed ceil)
- AVGFLOORU (unsigned floor)
- AVGCEILU (unsigned ceil)

Could you please review if I’ve missed anything?

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


More information about the llvm-commits mailing list