1 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ 2 // RUN: -o - | FileCheck %s --check-prefix=FULL 3 4 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ 5 // RUN: -complex-range=basic -o - | FileCheck --check-prefix=BASIC %s 6 7 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ 8 // RUN: -fno-cx-limited-range -o - | FileCheck %s --check-prefix=FULL 9 10 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ 11 // RUN: -complex-range=improved -o - | FileCheck --check-prefix=IMPRVD %s 12 13 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ 14 // RUN: -complex-range=promoted -o - | FileCheck --check-prefix=PRMTD %s 15 16 // RUN: %clang_cc1 %s -O0 -emit-llvm -triple x86_64-unknown-unknown \ 17 // RUN: -complex-range=full -o - | FileCheck --check-prefix=FULL %s 18 19 _Complex float pragma_on_mul(_Complex float a, _Complex float b) { 20 #pragma STDC CX_LIMITED_RANGE ON 21 // LABEL: define {{.*}} @pragma_on_mul( 22 23 // FULL: fmul float 24 // FULL-NEXT: fmul float 25 // FULL-NEXT: fmul float 26 // FULL-NEXT: fmul float 27 // FULL-NEXT: fsub float 28 // FULL-NEXT: fadd float 29 30 // BASIC: fmul float 31 // BASIC-NEXT: fmul float 32 // BASIC-NEXT: fmul float 33 // BASIC-NEXT: fmul float 34 // BASIC-NEXT: fsub float 35 // BASIC-NEXT: fadd float 36 37 // IMPRVD: fmul float 38 // IMPRVD-NEXT: fmul float 39 // IMPRVD-NEXT: fmul float 40 // IMPRVD-NEXT: fmul float 41 // IMPRVD-NEXT: fsub float 42 // IMPRVD-NEXT: fadd float 43 44 // PRMTD: fmul float 45 // PRMTD-NEXT: fmul float 46 // PRMTD-NEXT: fmul float 47 // PRMTD-NEXT: fmul float 48 // PRMTD-NEXT: fsub float 49 // PRMTD-NEXT: fadd float 50 51 return a * b; 52 } 53 54 _Complex float pragma_off_mul(_Complex float a, _Complex float b) { 55 #pragma STDC CX_LIMITED_RANGE OFF 56 // LABEL: define {{.*}} @pragma_off_mul( 57 58 // FULL: call {{.*}} @__mulsc3 59 60 // BASIC: call {{.*}} @__mulsc3 61 62 // IMPRVD: call {{.*}} @__mulsc3 63 64 // PRMTD: call {{.*}} @__mulsc3 65 66 return a * b; 67 } 68 69 _Complex float pragma_on_div(_Complex float a, _Complex float b) { 70 #pragma STDC CX_LIMITED_RANGE ON 71 // LABEL: define {{.*}} @pragma_on_div( 72 73 // FULL: fmul float 74 // FULL-NEXT: fmul float 75 // FULL-NEXT: fadd float 76 // FULL-NEXT: fmul float 77 // FULL-NEXT: fmul float 78 // FULL-NEXT: fadd float 79 // FULL-NEXT: fmul float 80 // FULL-NEXT: fmul float 81 // FULL-NEXT: fsub float 82 // FULL-NEXT: fdiv float 83 // FULL: fdiv float 84 85 // BASIC: fmul float 86 // BASIC-NEXT: fmul float 87 // BASIC-NEXT: fadd float 88 // BASIC-NEXT: fmul float 89 // BASIC-NEXT: fmul float 90 // BASIC-NEXT: fadd float 91 // BASIC-NEXT: fmul float 92 // BASIC-NEXT: fmul float 93 // BASIC-NEXT: fsub float 94 // BASIC-NEXT: fdiv float 95 // BASIC-NEXT: fdiv float 96 97 // IMPRVD: fmul float 98 // IMPRVD-NEXT: fmul float 99 // IMPRVD-NEXT: fadd float 100 // IMPRVD-NEXT: fmul float 101 // IMPRVD-NEXT: fmul float 102 // IMPRVD-NEXT: fadd float 103 // IMPRVD-NEXT: fmul float 104 // IMPRVD-NEXT: fmul float 105 // IMPRVD-NEXT: fsub float 106 // IMPRVD-NEXT: fdiv float 107 // IMPRVD-NEXT: fdiv float 108 109 // PRMTD: fmul float 110 // PRMTD-NEXT: fmul float 111 // PRMTD-NEXT: fadd float 112 // PRMTD-NEXT: fmul float 113 // PRMTD-NEXT: fmul float 114 // PRMTD-NEXT: fadd float 115 // PRMTD-NEXT: fmul float 116 // PRMTD-NEXT: fmul float 117 // PRMTD-NEXT: fsub float 118 // PRMTD-NEXT: fdiv float 119 // PRMTD-NEXT: fdiv float 120 121 return a / b; 122 } 123 124 _Complex float pragma_off_div(_Complex float a, _Complex float b) { 125 #pragma STDC CX_LIMITED_RANGE OFF 126 // LABEL: define {{.*}} @pragma_off_div( 127 128 // FULL: call {{.*}} @__divsc3 129 130 // BASIC: call {{.*}} @__divsc3 131 132 // IMPRVD: call {{.*}} @__divsc3 133 134 // PRMTD: call {{.*}} @__divsc3 135 136 return a / b; 137 } 138 139 _Complex float pragma_default_mul(_Complex float a, _Complex float b) { 140 #pragma STDC CX_LIMITED_RANGE DEFAULT 141 // LABEL: define {{.*}} @pragma_on_mul( 142 143 // FULL: fmul float 144 // FULL-NEXT: fmul float 145 // FULL-NEXT: fmul float 146 // FULL-NEXT: fmul float 147 // FULL-NEXT: fsub float 148 // FULL-NEXT: fadd float 149 150 // BASIC: fmul float 151 // BASIC-NEXT: fmul float 152 // BASIC-NEXT: fmul float 153 // BASIC-NEXT: fmul float 154 // BASIC-NEXT: fsub float 155 // BASIC-NEXT: fadd float 156 157 // IMPRVD: fmul float 158 // IMPRVD-NEXT: fmul float 159 // IMPRVD-NEXT: fmul float 160 // IMPRVD-NEXT: fmul float 161 // IMPRVD-NEXT: fsub float 162 // IMPRVD-NEXT: fadd float 163 164 // PRMTD: fmul float 165 // PRMTD-NEXT: fmul float 166 // PRMTD-NEXT: fmul float 167 // PRMTD-NEXT: fmul float 168 // PRMTD-NEXT: fsub float 169 // PRMTD-NEXT: fadd float 170 171 return a * b; 172 } 173 _Complex float pragma_default_div(_Complex float a, _Complex float b) { 174 #pragma STDC CX_LIMITED_RANGE DEFAULT 175 // LABEL: define {{.*}} @pragma_on_divx( 176 177 // FULL: call {{.*}} @__divsc3 178 179 // BASIC: fmul float 180 // BASIC-NEXT: fmul float 181 // BASIC-NEXT: fadd float 182 // BASIC-NEXT: fmul float 183 // BASIC-NEXT: fmul float 184 // BASIC-NEXT: fadd float 185 // BASIC-NEXT: fmul float 186 // BASIC-NEXT: fmul float 187 // BASIC-NEXT: fsub float 188 // BASIC-NEXT: fdiv float 189 // BASIC-NEXT: fdiv float 190 191 // IMPRVD: call{{.*}}float @llvm.fabs.f32(float {{.*}}) 192 // IMPRVD-NEXT: call{{.*}}float @llvm.fabs.f32(float {{.*}}) 193 // IMPRVD-NEXT: fcmp{{.*}}ugt float {{.*}}, {{.*}} 194 // IMPRVD-NEXT: br i1 {{.*}}, label 195 // IMPRVD: abs_rhsr_greater_or_equal_abs_rhsi: 196 // IMPRVD-NEXT: fdiv float 197 // IMPRVD-NEXT: fmul float 198 // IMPRVD-NEXT: fadd float 199 // IMPRVD-NEXT: fmul float 200 // IMPRVD-NEXT: fadd float 201 // IMPRVD-NEXT: fdiv float 202 // IMPRVD-NEXT: fmul float 203 // IMPRVD-NEXT: fsub float 204 // IMPRVD-NEXT: fdiv float 205 // IMPRVD-NEXT: br label 206 // IMPRVD: abs_rhsr_less_than_abs_rhsi: 207 // IMPRVD-NEXT: fdiv float 208 // IMPRVD-NEXT: fmul float 209 // IMPRVD-NEXT: fadd float 210 // IMPRVD-NEXT: fmul float 211 // IMPRVD-NEXT: fadd float 212 // IMPRVD-NEXT: fdiv float 213 // IMPRVD-NEXT: fmul float 214 // IMPRVD-NEXT: fsub float 215 // IMPRVD-NEXT: fdiv float 216 217 // PRMTD: load float, ptr {{.*}} 218 // PRMTD: fpext float {{.*}} to double 219 // PRMTD-NEXT: fpext float {{.*}} to double 220 // PRMTD-NEXT: getelementptr inbounds nuw { float, float }, ptr {{.*}}, i32 0, i32 0 221 // PRMTD-NEXT: load float, ptr {{.*}} 222 // PRMTD-NEXT: getelementptr inbounds nuw { float, float }, ptr {{.*}}, i32 0, i32 1 223 // PRMTD-NEXT: load float, ptr {{.*}} 224 // PRMTD-NEXT: fpext float {{.*}} to double 225 // PRMTD-NEXT: fpext float {{.*}} to double 226 // PRMTD-NEXT: fmul double 227 // PRMTD-NEXT: fmul double 228 // PRMTD-NEXT: fadd double 229 // PRMTD-NEXT: fmul double 230 // PRMTD-NEXT: fmul double 231 // PRMTD-NEXT: fadd double 232 // PRMTD-NEXT: fmul double 233 // PRMTD-NEXT: fmul double 234 // PRMTD-NEXT: fsub double 235 // PRMTD-NEXT: fdiv double 236 // PRMTD-NEXT: fdiv double 237 // PRMTD-NEXT: fptrunc double {{.*}} to float 238 // PRMTD-NEXT: fptrunc double {{.*}} to float 239 240 return a / b; 241 } 242