Skip to content

Commit 9cbac91

Browse files
[flang] Add test for fp conversions
Semantics for floating point conversions to integer types was changed in flang to use the saturated floating point intrinsics to more closely match the standard semantics in llvm-project#130686 . This tests conversions from tiny, huge and inf to various integer types.
1 parent 491a015 commit 9cbac91

File tree

5 files changed

+162
-0
lines changed

5 files changed

+162
-0
lines changed

Fortran/UnitTests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ add_subdirectory(assign-goto)
44
add_subdirectory(execute_command_line)
55
add_subdirectory(fcvs21_f95) # NIST Fortran Compiler Validation Suite
66
add_subdirectory(finalization)
7+
add_subdirectory(fp_conversions)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
list(APPEND FFLAGS -funsigned)
2+
3+
llvm_singlesource()
4+
5+
file(COPY lit.local.cfg DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
module fp_convert_m
2+
use iso_fortran_env
3+
implicit none
4+
integer :: test_case = 1
5+
type answer
6+
integer(kind=1) :: i8
7+
integer(kind=2) :: i16
8+
integer(kind=4) :: i32
9+
integer(kind=8) :: i64
10+
unsigned(kind=1) :: u8
11+
unsigned(kind=2) :: u16
12+
unsigned(kind=4) :: u32
13+
unsigned(kind=8) :: u64
14+
end type answer
15+
type(answer) :: answers(6)
16+
17+
interface operator(==)
18+
module procedure answer_eq
19+
end interface operator(==)
20+
21+
contains
22+
23+
subroutine init_answers()
24+
! huge
25+
answers(1) = answer( &
26+
127, 32767, 2147483647, 9223372036854775807_8, &
27+
unsigned(255, kind=1), &
28+
unsigned(65535, kind=2), &
29+
unsigned(4294967295, kind=4), &
30+
unsigned(18446744073709551615, kind=8))
31+
32+
! -huge
33+
answers(2) = answer( &
34+
-128, -32768, -2147483648, -9223372036854775808_8, &
35+
unsigned(0, kind=1), &
36+
unsigned(0, kind=2), &
37+
unsigned(0, kind=4), &
38+
unsigned(0, kind=8))
39+
40+
! tiny
41+
answers(3) = answer( &
42+
0, 0, 0, 0, &
43+
unsigned(0, kind=1), &
44+
unsigned(0, kind=2), &
45+
unsigned(0, kind=4), &
46+
unsigned(0, kind=8))
47+
48+
! -tiny
49+
answers(4) = answers(3)
50+
51+
! inf
52+
answers(5) = answer( &
53+
127, 32767, 2147483647, 9223372036854775807_8, &
54+
unsigned(255, kind=1), &
55+
unsigned(65535, kind=2), &
56+
unsigned(4294967295, kind=4), &
57+
unsigned(18446744073709551615, kind=8))
58+
59+
! -inf
60+
answers(6) = answer( &
61+
-128, -32768, -2147483648, -9223372036854775808_8, &
62+
unsigned(0, kind=1), &
63+
unsigned(0, kind=2), &
64+
unsigned(0, kind=4), &
65+
unsigned(0, kind=8))
66+
end subroutine init_answers
67+
subroutine print_answer(a)
68+
type(answer), intent(in) :: a
69+
print *, a%i8, a%i16, a%i32, a%i64, a%u8, a%u16, a%u32, a%u64
70+
end subroutine print_answer
71+
72+
logical function answer_eq(a, b)
73+
type(answer), intent(in) :: a, b
74+
answer_eq = a%i8 == b%i8 .and. a%i16 == b%i16 .and. a%i32 == b%i32 .and. a%i64 == b%i64 &
75+
.and. a%u8 == b%u8 .and. a%u16 == b%u16 .and. a%u32 == b%u32 .and. a%u64 == b%u64
76+
end function answer_eq
77+
78+
subroutine do_conversion(value, result)
79+
real(kind=8), intent(in) :: value
80+
type(answer), intent(out) :: result
81+
result%i8 = int(value, kind=1)
82+
result%i16 = int(value, kind=2)
83+
result%i32 = int(value, kind=4)
84+
result%i64 = int(value, kind=8)
85+
86+
result%u8 = uint(value, kind=1)
87+
result%u16 = uint(value, kind=2)
88+
result%u32 = uint(value, kind=4)
89+
result%u64 = uint(value, kind=8)
90+
end subroutine
91+
92+
subroutine testcase(value, answers)
93+
real(kind=8), intent(in) :: value
94+
type(answer), intent(in) :: answers
95+
type(answer) :: result
96+
call do_conversion(value, result)
97+
if (result == answers) then
98+
print *, "PASS", test_case
99+
else
100+
print *, "FAIL", test_case
101+
print *, "Expected:"
102+
call print_answer(answers)
103+
print *, "Got:"
104+
call print_answer(result)
105+
end if
106+
test_case = test_case + 1
107+
end subroutine
108+
end module fp_convert_m
109+
110+
program fp_convert
111+
use ieee_arithmetic, only: ieee_value, ieee_quiet_nan, ieee_positive_inf, ieee_negative_inf
112+
use fp_convert_m
113+
implicit none
114+
115+
real(kind=8) :: r64, nan, inf, ninf
116+
117+
call init_answers()
118+
119+
nan = ieee_value(nan, ieee_quiet_nan)
120+
inf = ieee_value(inf, ieee_positive_inf)
121+
ninf = ieee_value(ninf, ieee_negative_inf)
122+
123+
print *, "huge"
124+
call testcase(huge(r64), answers(1))
125+
126+
print *, "-huge"
127+
call testcase(-huge(r64), answers(2))
128+
129+
print *, "tiny"
130+
call testcase(tiny(r64), answers(3))
131+
132+
print *, "-tiny"
133+
call testcase(-tiny(r64), answers(4))
134+
135+
print *, "inf"
136+
call testcase(inf, answers(5))
137+
138+
print *, "-inf"
139+
call testcase(ninf, answers(6))
140+
141+
end program fp_convert
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
huge
2+
PASS 1
3+
-huge
4+
PASS 2
5+
tiny
6+
PASS 3
7+
-tiny
8+
PASS 4
9+
inf
10+
PASS 5
11+
-inf
12+
PASS 6
13+
exit 0
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
config.traditional_output = True
2+
config.single_source = True

0 commit comments

Comments
 (0)