[llvm] [InstCombine] Add folds for `(fp_binop ({s|u}itofp x), ({s|u}itofp y))` (PR #82555)

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 21 16:17:55 PST 2024


goldsteinn wrote:

Result of all the proofs run locally:
```
; $> /home/noah/programs/opensource/llvm-dev/src/alive2/build/alive-tv (-smt-to=200000000)

----------------------------------------
define half @src_sisi_add_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = sadd_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = sitofp i8 noundef %x to half
  %yf = sitofp i8 noundef %y to half
  %r = fadd half %xf, %yf
  ret half %r
}
=>
define half @tgt_sisi_add_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = sadd_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = add i8 noundef %x, noundef %y
  %r = sitofp i8 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_uiui_add_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = uadd_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = uitofp i8 noundef %x to half
  %yf = uitofp i8 noundef %y to half
  %r = fadd half %xf, %yf
  ret half %r
}
=>
define half @tgt_uiui_add_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = uadd_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = add i8 noundef %x, noundef %y
  %r = uitofp i8 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_sisi_sub_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = ssub_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = sitofp i8 noundef %x to half
  %yf = sitofp i8 noundef %y to half
  %r = fsub half %xf, %yf
  ret half %r
}
=>
define half @tgt_sisi_sub_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = ssub_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = sub i8 noundef %x, noundef %y
  %r = sitofp i8 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_uiui_sub_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = usub_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = uitofp i8 noundef %x to half
  %yf = uitofp i8 noundef %y to half
  %r = fsub half %xf, %yf
  ret half %r
}
=>
define half @tgt_uiui_sub_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = usub_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = sub i8 noundef %x, noundef %y
  %r = uitofp i8 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_sisi_mul_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %x_okay = icmp ne i8 noundef %x, 0
  assume i1 %x_okay
  %y_okay = icmp ne i8 noundef %y, 0
  assume i1 %y_okay
  %overflow_info = smul_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = sitofp i8 noundef %x to half
  %yf = sitofp i8 noundef %y to half
  %r = fmul half %xf, %yf
  ret half %r
}
=>
define half @tgt_sisi_mul_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %x_okay = icmp ne i8 noundef %x, 0
  assume i1 %x_okay
  %y_okay = icmp ne i8 noundef %y, 0
  assume i1 %y_okay
  %overflow_info = smul_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = mul i8 noundef %x, noundef %y
  %r = sitofp i8 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_uiui_mul_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = umul_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = uitofp i8 noundef %x to half
  %yf = uitofp i8 noundef %y to half
  %r = fmul half %xf, %yf
  ret half %r
}
=>
define half @tgt_uiui_mul_i8(i8 noundef %x, i8 noundef %y) {
#0:
  %overflow_info = umul_overflow i8 noundef %x, noundef %y
  %does_overflow = extractvalue {i8, i1} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = mul i8 noundef %x, noundef %y
  %r = uitofp i8 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_sisi_add_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_high_zeros = icmp ule i16 noundef %x, 2048
  %x_high_ones = icmp uge i16 noundef %x, 63488
  %x_okay = or i1 %x_high_zeros, %x_high_ones
  assume i1 %x_okay
  %y_high_zeros = icmp ule i16 noundef %y, 2048
  %y_high_ones = icmp uge i16 noundef %y, 63488
  %y_okay = or i1 %y_high_zeros, %y_high_ones
  assume i1 %y_okay
  %xf = sitofp i16 noundef %x to half
  %yf = sitofp i16 noundef %y to half
  %r = fadd half %xf, %yf
  ret half %r
}
=>
define half @tgt_sisi_add_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_high_zeros = icmp ule i16 noundef %x, 2048
  %x_high_ones = icmp uge i16 noundef %x, 63488
  %x_okay = or i1 %x_high_zeros, %x_high_ones
  assume i1 %x_okay
  %y_high_zeros = icmp ule i16 noundef %y, 2048
  %y_high_ones = icmp uge i16 noundef %y, 63488
  %y_okay = or i1 %y_high_zeros, %y_high_ones
  assume i1 %y_okay
  %xy = add i16 noundef %x, noundef %y
  %r = sitofp i16 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_uiui_add_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_okay = icmp ule i16 noundef %x, 2048
  assume i1 %x_okay
  %y_okay = icmp ule i16 noundef %y, 2048
  assume i1 %y_okay
  %xf = uitofp i16 noundef %x to half
  %yf = uitofp i16 noundef %y to half
  %r = fadd half %xf, %yf
  ret half %r
}
=>
define half @tgt_uiui_add_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_okay = icmp ule i16 noundef %x, 2048
  assume i1 %x_okay
  %y_okay = icmp ule i16 noundef %y, 2048
  assume i1 %y_okay
  %xy = add i16 noundef %x, noundef %y
  %r = uitofp i16 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_sisi_sub_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_high_zeros = icmp ule i16 noundef %x, 2048
  %x_high_ones = icmp uge i16 noundef %x, 63488
  %x_okay = or i1 %x_high_zeros, %x_high_ones
  assume i1 %x_okay
  %y_high_zeros = icmp ule i16 noundef %y, 2048
  %y_high_ones = icmp uge i16 noundef %y, 63488
  %y_okay = or i1 %y_high_zeros, %y_high_ones
  assume i1 %y_okay
  %xf = sitofp i16 noundef %x to half
  %yf = sitofp i16 noundef %y to half
  %r = fsub half %xf, %yf
  ret half %r
}
=>
define half @tgt_sisi_sub_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_high_zeros = icmp ule i16 noundef %x, 2048
  %x_high_ones = icmp uge i16 noundef %x, 63488
  %x_okay = or i1 %x_high_zeros, %x_high_ones
  assume i1 %x_okay
  %y_high_zeros = icmp ule i16 noundef %y, 2048
  %y_high_ones = icmp uge i16 noundef %y, 63488
  %y_okay = or i1 %y_high_zeros, %y_high_ones
  assume i1 %y_okay
  %xy = sub i16 noundef %x, noundef %y
  %r = sitofp i16 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_uiui_sub_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_okay = icmp ule i16 noundef %x, 2048
  assume i1 %x_okay
  %y_okay = icmp ule i16 noundef %y, 2048
  assume i1 %y_okay
  %xf = uitofp i16 noundef %x to half
  %yf = uitofp i16 noundef %y to half
  %r = fsub half %xf, %yf
  ret half %r
}
=>
define half @tgt_uiui_sub_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_okay = icmp ule i16 noundef %x, 2048
  assume i1 %x_okay
  %y_okay = icmp ule i16 noundef %y, 2048
  assume i1 %y_okay
  %xy = sub i16 noundef %x, noundef %y
  %r = sitofp i16 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_sisi_mul_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_high_zeros = icmp ule i16 noundef %x, 2048
  %x_high_ones = icmp uge i16 noundef %x, 63488
  %x_non_zero = icmp ne i16 noundef %x, 0
  %x_okay0 = or i1 %x_high_zeros, %x_high_ones
  %x_okay = and i1 %x_okay0, %x_non_zero
  assume i1 %x_okay
  %y_high_zeros = icmp ule i16 noundef %y, 2048
  %y_high_ones = icmp uge i16 noundef %y, 63488
  %y_non_zero = icmp ne i16 noundef %y, 0
  %y_okay0 = or i1 %y_high_zeros, %y_high_ones
  %y_okay = and i1 %y_okay0, %y_non_zero
  assume i1 %y_okay
  %overflow_info = smul_overflow i16 noundef %x, noundef %y
  %does_overflow = extractvalue {i16, i1, i8} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = sitofp i16 noundef %x to half
  %yf = sitofp i16 noundef %y to half
  %r = fmul half %xf, %yf
  ret half %r
}
=>
define half @tgt_sisi_mul_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_high_zeros = icmp ule i16 noundef %x, 2048
  %x_high_ones = icmp uge i16 noundef %x, 63488
  %x_non_zero = icmp ne i16 noundef %x, 0
  %x_okay0 = or i1 %x_high_zeros, %x_high_ones
  %x_okay = and i1 %x_okay0, %x_non_zero
  assume i1 %x_okay
  %y_high_zeros = icmp ule i16 noundef %y, 2048
  %y_high_ones = icmp uge i16 noundef %y, 63488
  %y_non_zero = icmp ne i16 noundef %y, 0
  %y_okay0 = or i1 %y_high_zeros, %y_high_ones
  %y_okay = and i1 %y_okay0, %y_non_zero
  assume i1 %y_okay
  %overflow_info = smul_overflow i16 noundef %x, noundef %y
  %does_overflow = extractvalue {i16, i1, i8} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = mul i16 noundef %x, noundef %y
  %r = sitofp i16 %xy to half
  ret half %r
}
Transformation seems to be correct!


----------------------------------------
define half @src_uiui_mul_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_okay = icmp ule i16 noundef %x, 2048
  assume i1 %x_okay
  %y_okay = icmp ule i16 noundef %y, 2048
  assume i1 %y_okay
  %overflow_info = umul_overflow i16 noundef %x, noundef %y
  %does_overflow = extractvalue {i16, i1, i8} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xf = uitofp i16 noundef %x to half
  %yf = uitofp i16 noundef %y to half
  %r = fmul half %xf, %yf
  ret half %r
}
=>
define half @tgt_uiui_mul_i16(i16 noundef %x, i16 noundef %y) {
#0:
  %x_okay = icmp ule i16 noundef %x, 2048
  assume i1 %x_okay
  %y_okay = icmp ule i16 noundef %y, 2048
  assume i1 %y_okay
  %overflow_info = umul_overflow i16 noundef %x, noundef %y
  %does_overflow = extractvalue {i16, i1, i8} %overflow_info, 1
  %doesnot_overflow = xor i1 %does_overflow, 1
  assume i1 %doesnot_overflow
  %xy = mul i16 noundef %x, noundef %y
  %r = uitofp i16 %xy to half
  ret half %r
}
Transformation seems to be correct!

Summary:
  12 correct transformations
  0 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors

```

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


More information about the llvm-commits mailing list