Luke Lau 19b0e1227c
[ConstantFolding] Fold sqrt poison -> poison (#141821)
I noticed this when a sqrt produced by VectorCombine with a poison
operand wasn't getting folded away to poison.

Most intrinsics in general could probably be folded to poison if one of
their arguments are poison too. Are there any exceptions to this we need
to be aware of?
2025-06-11 13:27:14 +02:00

346 lines
7.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
define float @fadd_undef_op0(float %x) {
; CHECK-LABEL: @fadd_undef_op0(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fadd float undef, %x
ret float %r
}
define float @fadd_poison_op0(float %x) {
; CHECK-LABEL: @fadd_poison_op0(
; CHECK-NEXT: ret float poison
;
%r = fadd float poison, %x
ret float %r
}
define float @fadd_undef_op1(float %x) {
; CHECK-LABEL: @fadd_undef_op1(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fadd float %x, undef
ret float %r
}
define float @fadd_poison_op1(float %x) {
; CHECK-LABEL: @fadd_poison_op1(
; CHECK-NEXT: ret float poison
;
%r = fadd float %x, poison
ret float %r
}
define float @fsub_undef_op0(float %x) {
; CHECK-LABEL: @fsub_undef_op0(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fsub float undef, %x
ret float %r
}
define float @fsub_poison_op0(float %x) {
; CHECK-LABEL: @fsub_poison_op0(
; CHECK-NEXT: ret float poison
;
%r = fsub float poison, %x
ret float %r
}
define float @fsub_undef_op1(float %x) {
; CHECK-LABEL: @fsub_undef_op1(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fsub float %x, undef
ret float %r
}
define float @fsub_poison_op1(float %x) {
; CHECK-LABEL: @fsub_poison_op1(
; CHECK-NEXT: ret float poison
;
%r = fsub float %x, poison
ret float %r
}
define float @fmul_undef_op0(float %x) {
; CHECK-LABEL: @fmul_undef_op0(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fmul float undef, %x
ret float %r
}
define float @fmul_poison_op0(float %x) {
; CHECK-LABEL: @fmul_poison_op0(
; CHECK-NEXT: ret float poison
;
%r = fmul float poison, %x
ret float %r
}
define float @fmul_undef_op1(float %x) {
; CHECK-LABEL: @fmul_undef_op1(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fmul float %x, undef
ret float %r
}
define float @fmul_poison_op1(float %x) {
; CHECK-LABEL: @fmul_poison_op1(
; CHECK-NEXT: ret float poison
;
%r = fmul float %x, poison
ret float %r
}
define float @fdiv_undef_op0(float %x) {
; CHECK-LABEL: @fdiv_undef_op0(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fdiv float undef, %x
ret float %r
}
define float @fdiv_poison_op0(float %x) {
; CHECK-LABEL: @fdiv_poison_op0(
; CHECK-NEXT: ret float poison
;
%r = fdiv float poison, %x
ret float %r
}
define float @fdiv_undef_op1(float %x) {
; CHECK-LABEL: @fdiv_undef_op1(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = fdiv float %x, undef
ret float %r
}
define float @fdiv_poison_op1(float %x) {
; CHECK-LABEL: @fdiv_poison_op1(
; CHECK-NEXT: ret float poison
;
%r = fdiv float %x, poison
ret float %r
}
define float @frem_undef_op0(float %x) {
; CHECK-LABEL: @frem_undef_op0(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = frem float undef, %x
ret float %r
}
define float @frem_poison_op0(float %x) {
; CHECK-LABEL: @frem_poison_op0(
; CHECK-NEXT: ret float poison
;
%r = frem float poison, %x
ret float %r
}
define float @frem_undef_op1(float %x) {
; CHECK-LABEL: @frem_undef_op1(
; CHECK-NEXT: ret float 0x7FF8000000000000
;
%r = frem float %x, undef
ret float %r
}
define float @frem_poison_op1(float %x) {
; CHECK-LABEL: @frem_poison_op1(
; CHECK-NEXT: ret float poison
;
%r = frem float %x, poison
ret float %r
}
; Repeat all tests with fast-math-flags. Alternate 'nnan' and 'fast' for more coverage.
define float @fadd_undef_op0_nnan(float %x) {
; CHECK-LABEL: @fadd_undef_op0_nnan(
; CHECK-NEXT: ret float poison
;
%r = fadd nnan float undef, %x
ret float %r
}
define float @fadd_undef_op1_fast(float %x) {
; CHECK-LABEL: @fadd_undef_op1_fast(
; CHECK-NEXT: ret float poison
;
%r = fadd fast float %x, undef
ret float %r
}
define float @fsub_undef_op0_fast(float %x) {
; CHECK-LABEL: @fsub_undef_op0_fast(
; CHECK-NEXT: ret float poison
;
%r = fsub fast float undef, %x
ret float %r
}
define float @fsub_undef_op1_nnan(float %x) {
; CHECK-LABEL: @fsub_undef_op1_nnan(
; CHECK-NEXT: ret float poison
;
%r = fsub nnan float %x, undef
ret float %r
}
define float @fmul_undef_op0_nnan(float %x) {
; CHECK-LABEL: @fmul_undef_op0_nnan(
; CHECK-NEXT: ret float poison
;
%r = fmul nnan float undef, %x
ret float %r
}
define float @fmul_undef_op1_fast(float %x) {
; CHECK-LABEL: @fmul_undef_op1_fast(
; CHECK-NEXT: ret float poison
;
%r = fmul fast float %x, undef
ret float %r
}
define float @fdiv_undef_op0_fast(float %x) {
; CHECK-LABEL: @fdiv_undef_op0_fast(
; CHECK-NEXT: ret float poison
;
%r = fdiv fast float undef, %x
ret float %r
}
define float @fdiv_undef_op1_nnan(float %x) {
; CHECK-LABEL: @fdiv_undef_op1_nnan(
; CHECK-NEXT: ret float poison
;
%r = fdiv nnan float %x, undef
ret float %r
}
define float @frem_undef_op0_nnan(float %x) {
; CHECK-LABEL: @frem_undef_op0_nnan(
; CHECK-NEXT: ret float poison
;
%r = frem nnan float undef, %x
ret float %r
}
define float @frem_undef_op1_fast(float %x) {
; CHECK-LABEL: @frem_undef_op1_fast(
; CHECK-NEXT: ret float poison
;
%r = frem fast float %x, undef
ret float %r
}
define double @fdiv_ninf_nan_op0(double %x) {
; CHECK-LABEL: @fdiv_ninf_nan_op0(
; CHECK-NEXT: ret double 0xFFF8000000000000
;
%r = fdiv ninf double 0xfff8000000000000, %x
ret double %r
}
define double @fadd_ninf_nan_op1(double %x) {
; CHECK-LABEL: @fadd_ninf_nan_op1(
; CHECK-NEXT: ret double 0x7FF8000000000000
;
%r = fadd ninf double %x, 0x7ff8000000000000
ret double %r
}
define double @fdiv_ninf_inf_op0(double %x) {
; CHECK-LABEL: @fdiv_ninf_inf_op0(
; CHECK-NEXT: ret double poison
;
%r = fdiv ninf double 0x7ff0000000000000, %x
ret double %r
}
define double @fadd_ninf_inf_op1(double %x) {
; CHECK-LABEL: @fadd_ninf_inf_op1(
; CHECK-NEXT: ret double poison
;
%r = fadd ninf double %x, 0xfff0000000000000
ret double %r
}
define double @fsub_nnan_inf_op0(double %x) {
; CHECK-LABEL: @fsub_nnan_inf_op0(
; CHECK-NEXT: ret double 0x7FF0000000000000
;
%r = fsub nnan double 0x7ff0000000000000, %x
ret double %r
}
; This can't simplify - the result is infinity, but the sign is unknown.
define double @fmul_nnan_inf_op1(double %x) {
; CHECK-LABEL: @fmul_nnan_inf_op1(
; CHECK-NEXT: [[R:%.*]] = fmul nnan double [[X:%.*]], 0xFFF0000000000000
; CHECK-NEXT: ret double [[R]]
;
%r = fmul nnan double %x, 0xfff0000000000000
ret double %r
}
define float @sqrt_poison() {
; CHECK-LABEL: @sqrt_poison(
; CHECK-NEXT: ret float poison
;
%sqrt = call float @llvm.sqrt(float poison)
ret float %sqrt
}
define <2 x float> @sqrt_poison_fixed_vec() {
; CHECK-LABEL: @sqrt_poison_fixed_vec(
; CHECK-NEXT: ret <2 x float> poison
;
%sqrt = call <2 x float> @llvm.sqrt(<2 x float> poison)
ret <2 x float> %sqrt
}
define <2 x float> @sqrt_poison_elt_fixed_vec() {
; CHECK-LABEL: @sqrt_poison_elt_fixed_vec(
; CHECK-NEXT: ret <2 x float> <float 1.000000e+00, float poison>
;
%sqrt = call <2 x float> @llvm.sqrt(<2 x float> <float 1.0, float poison>)
ret <2 x float> %sqrt
}
define <vscale x 2 x float> @sqrt_poison_scalable_vec() {
; CHECK-LABEL: @sqrt_poison_scalable_vec(
; CHECK-NEXT: ret <vscale x 2 x float> poison
;
%sqrt = call <vscale x 2 x float> @llvm.sqrt(<vscale x 2 x float> poison)
ret <vscale x 2 x float> %sqrt
}
define float @sqrt_nnan_nan() {
; CHECK-LABEL: @sqrt_nnan_nan(
; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @llvm.sqrt.f32(float 0x7FF8000000000000)
; CHECK-NEXT: ret float [[SQRT]]
;
%sqrt = call nnan float @llvm.sqrt(float 0x7ff8000000000000)
ret float %sqrt
}
define float @sqrt_ninf_inf() {
; CHECK-LABEL: @sqrt_ninf_inf(
; CHECK-NEXT: [[SQRT:%.*]] = call ninf float @llvm.sqrt.f32(float 0xFFF0000000000000)
; CHECK-NEXT: ret float [[SQRT]]
;
%sqrt = call ninf float @llvm.sqrt(float 0xfff0000000000000)
ret float %sqrt
}