1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00
llvm-mirror/test/CodeGen/AArch64/fp-const-fold.ll
Sanjay Patel 611aa86281 [SDAG] simplify FP binops to undef
As discussed in the commit thread for rGa253a2a and D73978, we can do more undef folding for FP ops.
The nnan and ninf fast-math-flags specify that if an operand is the disallowed value, the result is
poison, so we can produce an undef result.

But this doesn't work as expected (the undef operand cases remain) because of a Flags propagation
problem in SelectionDAGBuilder.

I've added DAGCombiner calls to enable these for the other cases because we've shown in other
patches that (because of the limited way that SDAG iterates), it is possible to miss simplifications
like this if they are done only at node creation time.

Several potential follow-ups to expand on this patch are possible.

Differential Revision: https://reviews.llvm.org/D75576
2020-03-04 10:42:16 -05:00

213 lines
5.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
; https://bugs.llvm.org/show_bug.cgi?id=41668
define double @constant_fold_fdiv_by_zero(double* %p) {
; CHECK-LABEL: constant_fold_fdiv_by_zero:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9218868437227405312
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fdiv double 4.940660e-324, 0.0
ret double %r
}
; frem by 0.0 --> NaN
define double @constant_fold_frem_by_zero(double* %p) {
; CHECK-LABEL: constant_fold_frem_by_zero:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = frem double 4.940660e-324, 0.0
ret double %r
}
; Inf * 0.0 --> NaN
define double @constant_fold_fmul_nan(double* %p) {
; CHECK-LABEL: constant_fold_fmul_nan:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fmul double 0x7ff0000000000000, 0.0
ret double %r
}
; Inf + -Inf --> NaN
define double @constant_fold_fadd_nan(double* %p) {
; CHECK-LABEL: constant_fold_fadd_nan:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fadd double 0x7ff0000000000000, 0xfff0000000000000
ret double %r
}
; Inf - Inf --> NaN
define double @constant_fold_fsub_nan(double* %p) {
; CHECK-LABEL: constant_fold_fsub_nan:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fsub double 0x7ff0000000000000, 0x7ff0000000000000
ret double %r
}
; Inf * 0.0 + ? --> NaN
define double @constant_fold_fma_nan(double* %p) {
; CHECK-LABEL: constant_fold_fma_nan:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = call double @llvm.fma.f64(double 0x7ff0000000000000, double 0.0, double 42.0)
ret double %r
}
define double @fdiv_nnan_nan_op0(double %x) {
; CHECK-LABEL: fdiv_nnan_nan_op0:
; CHECK: // %bb.0:
; CHECK-NEXT: ret
%r = fdiv nnan double 0xfff8000000000000, %x
ret double %r
}
define double @fmul_nnan_nan_op1(double %x) {
; CHECK-LABEL: fmul_nnan_nan_op1:
; CHECK: // %bb.0:
; CHECK-NEXT: ret
%r = fmul nnan double %x, 0x7ff8000000000000
ret double %r
}
; Negative test - nan is ok.
; TODO: Should simplify to nan.
define double @fdiv_ninf_nan_op0(double %x) {
; CHECK-LABEL: fdiv_ninf_nan_op0:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #-2251799813685248
; CHECK-NEXT: fmov d1, x8
; CHECK-NEXT: fdiv d0, d1, d0
; CHECK-NEXT: ret
%r = fdiv ninf double 0xfff8000000000000, %x
ret double %r
}
; Negative test - nan is ok.
; TODO: Should simplify to nan.
define double @fadd_ninf_nan_op1(double %x) {
; CHECK-LABEL: fadd_ninf_nan_op1:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d1, x8
; CHECK-NEXT: fadd d0, d0, d1
; CHECK-NEXT: ret
%r = fadd ninf double %x, 0x7ff8000000000000
ret double %r
}
define double @fdiv_ninf_inf_op0(double %x) {
; CHECK-LABEL: fdiv_ninf_inf_op0:
; CHECK: // %bb.0:
; CHECK-NEXT: ret
%r = fdiv ninf double 0x7ff0000000000000, %x
ret double %r
}
define double @fadd_ninf_inf_op1(double %x) {
; CHECK-LABEL: fadd_ninf_inf_op1:
; CHECK: // %bb.0:
; CHECK-NEXT: ret
%r = fadd ninf double %x, 0xfff0000000000000
ret double %r
}
; Negative test - inf is ok.
; TODO: Should simplify to inf.
define double @fsub_nnan_inf_op0(double %x) {
; CHECK-LABEL: fsub_nnan_inf_op0:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9218868437227405312
; CHECK-NEXT: fmov d1, x8
; CHECK-NEXT: fsub d0, d1, d0
; CHECK-NEXT: ret
%r = fsub nnan double 0x7ff0000000000000, %x
ret double %r
}
; Negative test - inf is ok.
; TODO: Should simplify to -inf.
define double @fmul_nnan_inf_op1(double %x) {
; CHECK-LABEL: fmul_nnan_inf_op1:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #-4503599627370496
; CHECK-NEXT: fmov d1, x8
; CHECK-NEXT: fmul d0, d0, d1
; CHECK-NEXT: ret
%r = fmul nnan double %x, 0xfff0000000000000
ret double %r
}
; TODO: Should simplify to undef
define double @fdiv_nnan_undef_op0(double %x) {
; CHECK-LABEL: fdiv_nnan_undef_op0:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fdiv nnan double undef, %x
ret double %r
}
; TODO: Should simplify to undef
define double @fdiv_nnan_undef_op1(double %x) {
; CHECK-LABEL: fdiv_nnan_undef_op1:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fdiv nnan double %x, undef
ret double %r
}
; TODO: Should simplify to undef
define double @fdiv_ninf_undef_op0(double %x) {
; CHECK-LABEL: fdiv_ninf_undef_op0:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fdiv ninf double undef, %x
ret double %r
}
; TODO: Should simplify to undef
define double @fdiv_ninf_undef_op1(double %x) {
; CHECK-LABEL: fdiv_ninf_undef_op1:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x8, #9221120237041090560
; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
%r = fdiv ninf double %x, undef
ret double %r
}
declare double @llvm.fma.f64(double, double, double)