1 // RUN: %dexter --fail-lt 1.0 -w \
2 // RUN: --builder 'clang' --debugger 'lldb' \
3 // RUN: --cflags "-ffast-math -O2 -g" -- %s
4 // RUN: %dexter --fail-lt 1.0 -w \
5 // RUN: --builder 'clang' --debugger 'lldb' \
6 // RUN: --cflags "-ffast-math -O0 -g" -- %s
9 // UNSUPPORTED: system-windows
11 //// Check that the debugging experience with __attribute__((optnone)) at O2
12 //// matches O0. Test scalar floating point arithmetic with -ffast-math.
14 //// Example of strength reduction.
15 //// The division by 10.0f can be rewritten as a multiply by 0.1f.
16 //// A / 10.f ==> A * 0.1f
17 //// This is safe with fastmath since we treat the two operations
18 //// as equally precise. However we don't want this to happen
20 __attribute__((optnone
))
21 float test_fdiv(float A
) {
23 result
= A
/ 10.f
; // DexLabel('fdiv_assign')
24 return result
; // DexLabel('fdiv_ret')
26 // DexExpectWatchValue('A', 4, on_line=ref('fdiv_assign'))
27 // DexExpectWatchValue('result', '0.400000006', on_line=ref('fdiv_ret'))
29 //// (A * B) - (A * C) ==> A * (B - C)
30 __attribute__((optnone
))
31 float test_distributivity(float A
, float B
, float C
) {
34 float op2
= A
* C
; // DexLabel('distributivity_op2')
35 result
= op1
- op2
; // DexLabel('distributivity_result')
36 return result
; // DexLabel('distributivity_ret')
38 // DexExpectWatchValue('op1', '20', on_line=ref('distributivity_op2'))
39 // DexExpectWatchValue('op2', '24', on_line=ref('distributivity_result'))
40 // DexExpectWatchValue('result', '-4', on_line=ref('distributivity_ret'))
42 //// (A + B) + C == A + (B + C)
43 //// therefore, ((A + B) + C) + (A + (B + C)))
44 //// can be rewritten as
45 //// 2.0f * ((A + B) + C)
46 //// Clang is currently unable to spot this optimization
47 //// opportunity with fastmath.
48 __attribute__((optnone
))
49 float test_associativity(float A
, float B
, float C
) {
53 op1
+= C
; // DexLabel('associativity_op1')
55 result
= op1
+ op2
; // DexLabel('associativity_result')
56 return result
; // DexLabel('associativity_ret')
58 // DexExpectWatchValue('op1', '9', '15', from_line=ref('associativity_op1'), to_line=ref('associativity_result'))
59 // DexExpectWatchValue('op2', '11', '15', from_line=ref('associativity_op1'), to_line=ref('associativity_result'))
60 // DexExpectWatchValue('result', '30', on_line=ref('associativity_ret'))
62 //// With fastmath, the ordering of instructions doesn't matter
63 //// since we work under the assumption that there is no loss
64 //// in precision. This simplifies things for the optimizer which
65 //// can then decide to reorder instructions and fold
66 //// redundant operations like this:
71 //// This function can be simplified to a return A + B.
72 __attribute__((optnone
))
73 float test_simplify_fp_operations(float A
, float B
) {
74 float result
= A
+ 10.0f
; // DexLabel('fp_operations_result')
75 result
+= B
; // DexLabel('fp_operations_add')
77 return result
; // DexLabel('fp_operations_ret')
79 // DexExpectWatchValue('A', '8.25', on_line=ref('fp_operations_result'))
80 // DexExpectWatchValue('B', '26.3999996', on_line=ref('fp_operations_result'))
81 // DexExpectWatchValue('result', '18.25', '44.6500015', '34.6500015', from_line=ref('fp_operations_add'), to_line=ref('fp_operations_ret'))
83 //// Again, this is a simple return A + B.
84 //// Clang is unable to spot the opportunity to fold the code sequence.
85 __attribute__((optnone
))
86 float test_simplify_fp_operations_2(float A
, float B
, float C
) {
87 float result
= A
+ C
; // DexLabel('fp_operations_2_result')
89 result
-= C
; // DexLabel('fp_operations_2_subtract')
90 return result
; // DexLabel('fp_operations_2_ret')
92 // DexExpectWatchValue('A', '9.11999988', on_line=ref('fp_operations_2_result'))
93 // DexExpectWatchValue('B', '61.050003', on_line=ref('fp_operations_2_result'))
94 // DexExpectWatchValue('C', '1002.11102', on_line=ref('fp_operations_2_result'))
95 // DexExpectWatchValue('result', '1072.28101', '70.1699829', from_line=ref('fp_operations_2_subtract'), to_line=ref('fp_operations_2_ret'))
98 float result
= test_fdiv(4.0f
);
99 result
+= test_distributivity(4.0f
, 5.0f
, 6.0f
);
100 result
+= test_associativity(4.0f
, 5.0f
, 6.0f
);
101 result
+= test_simplify_fp_operations(8.25, result
);
102 result
+= test_simplify_fp_operations_2(9.12, result
, 1002.111);
103 return static_cast<int>(result
);