1 ; RUN: llc < %s -mtriple=ve | FileCheck %s
3 ;;; Test ‘frem’ Instruction
6 ;;; <result> = frem ptr <ty> <op1>, <op2> ; yields ty:result
9 ;;; The ‘frem’ instruction returns the remainder from the division of its two
13 ;;; The two arguments to the ‘frem’ instruction must be floating-point or
14 ;;; vector of floating-point values. Both arguments must have identical types.
17 ;;; The value produced is the floating-point remainder of the two operands.
18 ;;; This is the same output as a libm ‘fmod’ function, but without any
19 ;;; possibility of setting errno. The remainder has the same sign as the
20 ;;; dividend. This instruction is assumed to execute in the default
21 ;;; floating-point environment. This instruction can also take any number
22 ;;; of fast-math flags, which are optimization hints to enable otherwise
23 ;;; unsafe floating-point optimizations:
27 ;;; <result> = frem float 4.0, %var ; yields float:result = 4.0 % %var
30 ;;; We test only float/double/fp128.
31 ;;; We have no way to generated frem from C source code, so convert fdiv
32 ;;; to frem by using sed program.
34 ; Function Attrs: norecurse nounwind readnone
35 define float @frem_float_var(float %0, float %1) {
36 ; CHECK-LABEL: frem_float_var:
37 ; CHECK: .LBB{{[0-9]+}}_2:
38 ; CHECK-NEXT: lea %s2, fmodf@lo
39 ; CHECK-NEXT: and %s2, %s2, (32)0
40 ; CHECK-NEXT: lea.sl %s12, fmodf@hi(, %s2)
41 ; CHECK-NEXT: bsic %s10, (, %s12)
42 ; CHECK-NEXT: or %s11, 0, %s9
43 %3 = frem float %0, %1
47 ; Function Attrs: norecurse nounwind readnone
48 define double @frem_double_var(double %0, double %1) {
49 ; CHECK-LABEL: frem_double_var:
50 ; CHECK: .LBB{{[0-9]+}}_2:
51 ; CHECK-NEXT: lea %s2, fmod@lo
52 ; CHECK-NEXT: and %s2, %s2, (32)0
53 ; CHECK-NEXT: lea.sl %s12, fmod@hi(, %s2)
54 ; CHECK-NEXT: bsic %s10, (, %s12)
55 ; CHECK-NEXT: or %s11, 0, %s9
56 %3 = frem double %0, %1
60 ; Function Attrs: norecurse nounwind readnone
61 define fp128 @frem_quad_var(fp128 %0, fp128 %1) {
62 ; CHECK-LABEL: frem_quad_var:
63 ; CHECK: .LBB{{[0-9]+}}_2:
64 ; CHECK-NEXT: lea %s4, fmodl@lo
65 ; CHECK-NEXT: and %s4, %s4, (32)0
66 ; CHECK-NEXT: lea.sl %s12, fmodl@hi(, %s4)
67 ; CHECK-NEXT: bsic %s10, (, %s12)
68 ; CHECK-NEXT: or %s11, 0, %s9
69 %3 = frem fp128 %0, %1
73 ; Function Attrs: norecurse nounwind readnone
74 define float @frem_float_zero(float %0) {
75 ; CHECK-LABEL: frem_float_zero:
76 ; CHECK: .LBB{{[0-9]+}}_2:
77 ; CHECK-NEXT: or %s1, 0, %s0
78 ; CHECK-NEXT: lea %s0, fmodf@lo
79 ; CHECK-NEXT: and %s0, %s0, (32)0
80 ; CHECK-NEXT: lea.sl %s12, fmodf@hi(, %s0)
81 ; CHECK-NEXT: lea.sl %s0, 0
82 ; CHECK-NEXT: bsic %s10, (, %s12)
83 ; CHECK-NEXT: or %s11, 0, %s9
84 %2 = frem float 0.000000e+00, %0
88 ; Function Attrs: norecurse nounwind readnone
89 define double @frem_double_zero(double %0) {
90 ; CHECK-LABEL: frem_double_zero:
91 ; CHECK: .LBB{{[0-9]+}}_2:
92 ; CHECK-NEXT: or %s1, 0, %s0
93 ; CHECK-NEXT: lea %s0, fmod@lo
94 ; CHECK-NEXT: and %s0, %s0, (32)0
95 ; CHECK-NEXT: lea.sl %s12, fmod@hi(, %s0)
96 ; CHECK-NEXT: lea.sl %s0, 0
97 ; CHECK-NEXT: bsic %s10, (, %s12)
98 ; CHECK-NEXT: or %s11, 0, %s9
99 %2 = frem double 0.000000e+00, %0
103 ; Function Attrs: norecurse nounwind readnone
104 define fp128 @frem_quad_zero(fp128 %0) {
105 ; CHECK-LABEL: frem_quad_zero:
106 ; CHECK: .LBB{{[0-9]+}}_2:
107 ; CHECK-NEXT: or %s2, 0, %s0
108 ; CHECK-NEXT: or %s3, 0, %s1
109 ; CHECK-NEXT: lea %s0, .LCPI{{[0-9]+}}_0@lo
110 ; CHECK-NEXT: and %s0, %s0, (32)0
111 ; CHECK-NEXT: lea.sl %s4, .LCPI{{[0-9]+}}_0@hi(, %s0)
112 ; CHECK-NEXT: ld %s0, 8(, %s4)
113 ; CHECK-NEXT: ld %s1, (, %s4)
114 ; CHECK-NEXT: lea %s4, fmodl@lo
115 ; CHECK-NEXT: and %s4, %s4, (32)0
116 ; CHECK-NEXT: lea.sl %s12, fmodl@hi(, %s4)
117 ; CHECK-NEXT: bsic %s10, (, %s12)
118 ; CHECK-NEXT: or %s11, 0, %s9
119 %2 = frem fp128 0xL00000000000000000000000000000000, %0
123 ; Function Attrs: norecurse nounwind readnone
124 define float @frem_float_cont(float %0) {
125 ; CHECK-LABEL: frem_float_cont:
126 ; CHECK: .LBB{{[0-9]+}}_2:
127 ; CHECK-NEXT: or %s1, 0, %s0
128 ; CHECK-NEXT: lea %s0, fmodf@lo
129 ; CHECK-NEXT: and %s0, %s0, (32)0
130 ; CHECK-NEXT: lea.sl %s12, fmodf@hi(, %s0)
131 ; CHECK-NEXT: lea.sl %s0, -1073741824
132 ; CHECK-NEXT: bsic %s10, (, %s12)
133 ; CHECK-NEXT: or %s11, 0, %s9
134 %2 = frem float -2.000000e+00, %0
138 ; Function Attrs: norecurse nounwind readnone
139 define double @frem_double_cont(double %0) {
140 ; CHECK-LABEL: frem_double_cont:
141 ; CHECK: .LBB{{[0-9]+}}_2:
142 ; CHECK-NEXT: or %s1, 0, %s0
143 ; CHECK-NEXT: lea %s0, fmod@lo
144 ; CHECK-NEXT: and %s0, %s0, (32)0
145 ; CHECK-NEXT: lea.sl %s12, fmod@hi(, %s0)
146 ; CHECK-NEXT: lea.sl %s0, -1073741824
147 ; CHECK-NEXT: bsic %s10, (, %s12)
148 ; CHECK-NEXT: or %s11, 0, %s9
149 %2 = frem double -2.000000e+00, %0
153 ; Function Attrs: norecurse nounwind readnone
154 define fp128 @frem_quad_cont(fp128 %0) {
155 ; CHECK-LABEL: frem_quad_cont:
156 ; CHECK: .LBB{{[0-9]+}}_2:
157 ; CHECK-NEXT: or %s2, 0, %s0
158 ; CHECK-NEXT: or %s3, 0, %s1
159 ; CHECK-NEXT: lea %s0, .LCPI{{[0-9]+}}_0@lo
160 ; CHECK-NEXT: and %s0, %s0, (32)0
161 ; CHECK-NEXT: lea.sl %s4, .LCPI{{[0-9]+}}_0@hi(, %s0)
162 ; CHECK-NEXT: ld %s0, 8(, %s4)
163 ; CHECK-NEXT: ld %s1, (, %s4)
164 ; CHECK-NEXT: lea %s4, fmodl@lo
165 ; CHECK-NEXT: and %s4, %s4, (32)0
166 ; CHECK-NEXT: lea.sl %s12, fmodl@hi(, %s4)
167 ; CHECK-NEXT: bsic %s10, (, %s12)
168 ; CHECK-NEXT: or %s11, 0, %s9
169 %2 = frem fp128 0xL0000000000000000C000000000000000, %0