llvm-project/llvm/test/Assembler/fast-math-flags.ll

180 lines
6.0 KiB
LLVM
Raw Normal View History

; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; RUN: opt -S < %s | FileCheck %s
; RUN: verify-uselistorder %s
@addr = external global i64
@select = external global i1
@vec = external global <3 x float>
@arr = external global [3 x float]
[IR] redefine 'UnsafeAlgebra' / 'reassoc' fast-math-flags and add 'trans' fast-math-flag As discussed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-November/107104.html and again more recently: http://lists.llvm.org/pipermail/llvm-dev/2017-October/118118.html ...this is a step in cleaning up our fast-math-flags implementation in IR to better match the capabilities of both clang's user-visible flags and the backend's flags for SDNode. As proposed in the above threads, we're replacing the 'UnsafeAlgebra' bit (which had the 'umbrella' meaning that all flags are set) with a new bit that only applies to algebraic reassociation - 'AllowReassoc'. We're also adding a bit to allow approximations for library functions called 'ApproxFunc' (this was initially proposed as 'libm' or similar). ...and we're out of bits. 7 bits ought to be enough for anyone, right? :) FWIW, I did look at getting this out of SubclassOptionalData via SubclassData (spacious 16-bits), but that's apparently already used for other purposes. Also, I don't think we can just add a field to FPMathOperator because Operator is not intended to be instantiated. We'll defer movement of FMF to another day. We keep the 'fast' keyword. I thought about removing that, but seeing IR like this: %f.fast = fadd reassoc nnan ninf nsz arcp contract afn float %op1, %op2 ...made me think we want to keep the shortcut synonym. Finally, this change is binary incompatible with existing IR as seen in the compatibility tests. This statement: "Newer releases can ignore features from older releases, but they cannot miscompile them. For example, if nsw is ever replaced with something else, dropping it would be a valid way to upgrade the IR." ( http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility ) ...provides the flexibility we want to make this change without requiring a new IR version. Ie, we're not loosening the FP strictness of existing IR. At worst, we will fail to optimize some previously 'fast' code because it's no longer recognized as 'fast'. This should get fixed as we audit/squash all of the uses of 'isFast()'. Note: an inter-dependent clang commit to use the new API name should closely follow commit. Differential Revision: https://reviews.llvm.org/D39304 llvm-svn: 317488
2017-11-07 00:27:15 +08:00
declare float @foo(float)
define float @none(float %x, float %y) {
entry:
; CHECK: %vec = load <3 x float>, <3 x float>* @vec
%vec = load <3 x float>, <3 x float>* @vec
; CHECK: %select = load i1, i1* @select
%select = load i1, i1* @select
; CHECK: %arr = load [3 x float], [3 x float]* @arr
%arr = load [3 x float], [3 x float]* @arr
; CHECK: %a = fadd float %x, %y
%a = fadd float %x, %y
; CHECK: %a_vec = fadd <3 x float> %vec, %vec
%a_vec = fadd <3 x float> %vec, %vec
; CHECK: %b = fsub float %x, %y
%b = fsub float %x, %y
; CHECK: %b_vec = fsub <3 x float> %vec, %vec
%b_vec = fsub <3 x float> %vec, %vec
; CHECK: %c = fmul float %x, %y
%c = fmul float %x, %y
; CHECK: %c_vec = fmul <3 x float> %vec, %vec
%c_vec = fmul <3 x float> %vec, %vec
; CHECK: %d = fdiv float %x, %y
%d = fdiv float %x, %y
; CHECK: %d_vec = fdiv <3 x float> %vec, %vec
%d_vec = fdiv <3 x float> %vec, %vec
; CHECK: %e = frem float %x, %y
%e = frem float %x, %y
; CHECK: %e_vec = frem <3 x float> %vec, %vec
%e_vec = frem <3 x float> %vec, %vec
; CHECK: ret float %e
ret float %e
}
; CHECK: no_nan
define float @no_nan(float %x, float %y) {
entry:
; CHECK: %vec = load <3 x float>, <3 x float>* @vec
%vec = load <3 x float>, <3 x float>* @vec
; CHECK: %select = load i1, i1* @select
%select = load i1, i1* @select
; CHECK: %arr = load [3 x float], [3 x float]* @arr
%arr = load [3 x float], [3 x float]* @arr
; CHECK: %a = fadd nnan float %x, %y
%a = fadd nnan float %x, %y
; CHECK: %a_vec = fadd nnan <3 x float> %vec, %vec
%a_vec = fadd nnan <3 x float> %vec, %vec
; CHECK: %b = fsub nnan float %x, %y
%b = fsub nnan float %x, %y
; CHECK: %b_vec = fsub nnan <3 x float> %vec, %vec
%b_vec = fsub nnan <3 x float> %vec, %vec
; CHECK: %c = fmul nnan float %x, %y
%c = fmul nnan float %x, %y
; CHECK: %c_vec = fmul nnan <3 x float> %vec, %vec
%c_vec = fmul nnan <3 x float> %vec, %vec
; CHECK: %d = fdiv nnan float %x, %y
%d = fdiv nnan float %x, %y
; CHECK: %d_vec = fdiv nnan <3 x float> %vec, %vec
%d_vec = fdiv nnan <3 x float> %vec, %vec
; CHECK: %e = frem nnan float %x, %y
%e = frem nnan float %x, %y
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
%e_vec = frem nnan <3 x float> %vec, %vec
; CHECK: ret float %e
ret float %e
}
; CHECK: @contract(
define float @contract(float %x, float %y) {
entry:
; CHECK: %a = fsub contract float %x, %y
%a = fsub contract float %x, %y
; CHECK: %b = fadd contract float %x, %y
%b = fadd contract float %x, %y
; CHECK: %c = fmul contract float %a, %b
%c = fmul contract float %a, %b
ret float %c
}
[IR] redefine 'UnsafeAlgebra' / 'reassoc' fast-math-flags and add 'trans' fast-math-flag As discussed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-November/107104.html and again more recently: http://lists.llvm.org/pipermail/llvm-dev/2017-October/118118.html ...this is a step in cleaning up our fast-math-flags implementation in IR to better match the capabilities of both clang's user-visible flags and the backend's flags for SDNode. As proposed in the above threads, we're replacing the 'UnsafeAlgebra' bit (which had the 'umbrella' meaning that all flags are set) with a new bit that only applies to algebraic reassociation - 'AllowReassoc'. We're also adding a bit to allow approximations for library functions called 'ApproxFunc' (this was initially proposed as 'libm' or similar). ...and we're out of bits. 7 bits ought to be enough for anyone, right? :) FWIW, I did look at getting this out of SubclassOptionalData via SubclassData (spacious 16-bits), but that's apparently already used for other purposes. Also, I don't think we can just add a field to FPMathOperator because Operator is not intended to be instantiated. We'll defer movement of FMF to another day. We keep the 'fast' keyword. I thought about removing that, but seeing IR like this: %f.fast = fadd reassoc nnan ninf nsz arcp contract afn float %op1, %op2 ...made me think we want to keep the shortcut synonym. Finally, this change is binary incompatible with existing IR as seen in the compatibility tests. This statement: "Newer releases can ignore features from older releases, but they cannot miscompile them. For example, if nsw is ever replaced with something else, dropping it would be a valid way to upgrade the IR." ( http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility ) ...provides the flexibility we want to make this change without requiring a new IR version. Ie, we're not loosening the FP strictness of existing IR. At worst, we will fail to optimize some previously 'fast' code because it's no longer recognized as 'fast'. This should get fixed as we audit/squash all of the uses of 'isFast()'. Note: an inter-dependent clang commit to use the new API name should closely follow commit. Differential Revision: https://reviews.llvm.org/D39304 llvm-svn: 317488
2017-11-07 00:27:15 +08:00
; CHECK: @reassoc(
define float @reassoc(float %x, float %y) {
; CHECK: %a = fsub reassoc float %x, %y
%a = fsub reassoc float %x, %y
; CHECK: %b = fmul reassoc float %x, %y
%b = fmul reassoc float %x, %y
; CHECK: %c = call reassoc float @foo(float %b)
%c = call reassoc float @foo(float %b)
ret float %c
}
; CHECK: @afn(
define float @afn(float %x, float %y) {
; CHECK: %a = fdiv afn float %x, %y
%a = fdiv afn float %x, %y
; CHECK: %b = frem afn float %x, %y
%b = frem afn float %x, %y
; CHECK: %c = call afn float @foo(float %b)
%c = call afn float @foo(float %b)
ret float %c
}
; CHECK: no_nan_inf
define float @no_nan_inf(float %x, float %y) {
entry:
; CHECK: %vec = load <3 x float>, <3 x float>* @vec
%vec = load <3 x float>, <3 x float>* @vec
; CHECK: %select = load i1, i1* @select
%select = load i1, i1* @select
; CHECK: %arr = load [3 x float], [3 x float]* @arr
%arr = load [3 x float], [3 x float]* @arr
; CHECK: %a = fadd nnan ninf float %x, %y
%a = fadd ninf nnan float %x, %y
; CHECK: %a_vec = fadd nnan <3 x float> %vec, %vec
%a_vec = fadd nnan <3 x float> %vec, %vec
; CHECK: %b = fsub nnan float %x, %y
%b = fsub nnan float %x, %y
; CHECK: %b_vec = fsub nnan ninf <3 x float> %vec, %vec
%b_vec = fsub ninf nnan <3 x float> %vec, %vec
; CHECK: %c = fmul nnan float %x, %y
%c = fmul nnan float %x, %y
; CHECK: %c_vec = fmul nnan <3 x float> %vec, %vec
%c_vec = fmul nnan <3 x float> %vec, %vec
; CHECK: %d = fdiv nnan ninf float %x, %y
%d = fdiv ninf nnan float %x, %y
; CHECK: %d_vec = fdiv nnan <3 x float> %vec, %vec
%d_vec = fdiv nnan <3 x float> %vec, %vec
; CHECK: %e = frem nnan float %x, %y
%e = frem nnan float %x, %y
; CHECK: %e_vec = frem nnan ninf <3 x float> %vec, %vec
%e_vec = frem ninf nnan <3 x float> %vec, %vec
; CHECK: ret float %e
ret float %e
}
; CHECK: mixed_flags
define float @mixed_flags(float %x, float %y) {
entry:
; CHECK: %vec = load <3 x float>, <3 x float>* @vec
%vec = load <3 x float>, <3 x float>* @vec
; CHECK: %select = load i1, i1* @select
%select = load i1, i1* @select
; CHECK: %arr = load [3 x float], [3 x float]* @arr
%arr = load [3 x float], [3 x float]* @arr
[IR] redefine 'UnsafeAlgebra' / 'reassoc' fast-math-flags and add 'trans' fast-math-flag As discussed on llvm-dev: http://lists.llvm.org/pipermail/llvm-dev/2016-November/107104.html and again more recently: http://lists.llvm.org/pipermail/llvm-dev/2017-October/118118.html ...this is a step in cleaning up our fast-math-flags implementation in IR to better match the capabilities of both clang's user-visible flags and the backend's flags for SDNode. As proposed in the above threads, we're replacing the 'UnsafeAlgebra' bit (which had the 'umbrella' meaning that all flags are set) with a new bit that only applies to algebraic reassociation - 'AllowReassoc'. We're also adding a bit to allow approximations for library functions called 'ApproxFunc' (this was initially proposed as 'libm' or similar). ...and we're out of bits. 7 bits ought to be enough for anyone, right? :) FWIW, I did look at getting this out of SubclassOptionalData via SubclassData (spacious 16-bits), but that's apparently already used for other purposes. Also, I don't think we can just add a field to FPMathOperator because Operator is not intended to be instantiated. We'll defer movement of FMF to another day. We keep the 'fast' keyword. I thought about removing that, but seeing IR like this: %f.fast = fadd reassoc nnan ninf nsz arcp contract afn float %op1, %op2 ...made me think we want to keep the shortcut synonym. Finally, this change is binary incompatible with existing IR as seen in the compatibility tests. This statement: "Newer releases can ignore features from older releases, but they cannot miscompile them. For example, if nsw is ever replaced with something else, dropping it would be a valid way to upgrade the IR." ( http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility ) ...provides the flexibility we want to make this change without requiring a new IR version. Ie, we're not loosening the FP strictness of existing IR. At worst, we will fail to optimize some previously 'fast' code because it's no longer recognized as 'fast'. This should get fixed as we audit/squash all of the uses of 'isFast()'. Note: an inter-dependent clang commit to use the new API name should closely follow commit. Differential Revision: https://reviews.llvm.org/D39304 llvm-svn: 317488
2017-11-07 00:27:15 +08:00
; CHECK: %a = fadd nnan ninf afn float %x, %y
%a = fadd ninf nnan afn float %x, %y
; CHECK: %a_vec = fadd reassoc nnan <3 x float> %vec, %vec
%a_vec = fadd reassoc nnan <3 x float> %vec, %vec
; CHECK: %b = fsub fast float %x, %y
%b = fsub nnan nsz fast float %x, %y
; CHECK: %b_vec = fsub nnan <3 x float> %vec, %vec
%b_vec = fsub nnan <3 x float> %vec, %vec
; CHECK: %c = fmul fast float %x, %y
%c = fmul nsz fast arcp float %x, %y
; CHECK: %c_vec = fmul nsz <3 x float> %vec, %vec
%c_vec = fmul nsz <3 x float> %vec, %vec
; CHECK: %d = fdiv nnan ninf arcp float %x, %y
%d = fdiv arcp ninf nnan float %x, %y
; CHECK: %d_vec = fdiv fast <3 x float> %vec, %vec
%d_vec = fdiv fast nnan arcp <3 x float> %vec, %vec
; CHECK: %e = frem nnan nsz float %x, %y
%e = frem nnan nsz float %x, %y
; CHECK: %e_vec = frem nnan <3 x float> %vec, %vec
%e_vec = frem nnan <3 x float> %vec, %vec
; CHECK: ret float %e
ret float %e
}