1 ; RUN: opt < %s -instcombine -S | FileCheck %s 2 3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 4 target triple = "x86_64-unknown-linux-gnu" 5 6 ; Check for and against shrinkage when using the 7 ; unsafe-fp-math function attribute on a math lib 8 ; function. This optimization may be overridden by 9 ; the -enable-double-float-shrink option. 10 ; PR17850: http://llvm.org/bugs/show_bug.cgi?id=17850 11 12 define float @acos_test(float %f) { 13 %conv = fpext float %f to double 14 %call = call double @acos(double %conv) 15 %conv1 = fptrunc double %call to float 16 ret float %conv1 17 ; CHECK-LABEL: acos_test 18 ; CHECK: call float @acosf(float %f) 19 } 20 21 define double @acos_test2(float %f) { 22 %conv = fpext float %f to double 23 %call = call double @acos(double %conv) 24 ret double %call 25 ; CHECK-LABEL: acos_test2 26 ; CHECK: call double @acos(double %conv) 27 } 28 29 define float @acosh_test(float %f) { 30 %conv = fpext float %f to double 31 %call = call double @acosh(double %conv) 32 %conv1 = fptrunc double %call to float 33 ret float %conv1 34 ; CHECK-LABEL: acosh_test 35 ; CHECK: call float @acoshf(float %f) 36 } 37 38 define double @acosh_test2(float %f) { 39 %conv = fpext float %f to double 40 %call = call double @acosh(double %conv) 41 ret double %call 42 ; CHECK-LABEL: acosh_test2 43 ; CHECK: call double @acosh(double %conv) 44 } 45 46 define float @asin_test(float %f) { 47 %conv = fpext float %f to double 48 %call = call double @asin(double %conv) 49 %conv1 = fptrunc double %call to float 50 ret float %conv1 51 ; CHECK-LABEL: asin_test 52 ; CHECK: call float @asinf(float %f) 53 } 54 55 define double @asin_test2(float %f) { 56 %conv = fpext float %f to double 57 %call = call double @asin(double %conv) 58 ret double %call 59 ; CHECK-LABEL: asin_test2 60 ; CHECK: call double @asin(double %conv) 61 } 62 63 define float @asinh_test(float %f) { 64 %conv = fpext float %f to double 65 %call = call double @asinh(double %conv) 66 %conv1 = fptrunc double %call to float 67 ret float %conv1 68 ; CHECK-LABEL: asinh_test 69 ; CHECK: call float @asinhf(float %f) 70 } 71 72 define double @asinh_test2(float %f) { 73 %conv = fpext float %f to double 74 %call = call double @asinh(double %conv) 75 ret double %call 76 ; CHECK-LABEL: asinh_test2 77 ; CHECK: call double @asinh(double %conv) 78 } 79 80 define float @atan_test(float %f) { 81 %conv = fpext float %f to double 82 %call = call double @atan(double %conv) 83 %conv1 = fptrunc double %call to float 84 ret float %conv1 85 ; CHECK-LABEL: atan_test 86 ; CHECK: call float @atanf(float %f) 87 } 88 89 define double @atan_test2(float %f) { 90 %conv = fpext float %f to double 91 %call = call double @atan(double %conv) 92 ret double %call 93 ; CHECK-LABEL: atan_test2 94 ; CHECK: call double @atan(double %conv) 95 } 96 define float @atanh_test(float %f) { 97 %conv = fpext float %f to double 98 %call = call double @atanh(double %conv) 99 %conv1 = fptrunc double %call to float 100 ret float %conv1 101 ; CHECK-LABEL: atanh_test 102 ; CHECK: call float @atanhf(float %f) 103 } 104 105 define double @atanh_test2(float %f) { 106 %conv = fpext float %f to double 107 %call = call double @atanh(double %conv) 108 ret double %call 109 ; CHECK-LABEL: atanh_test2 110 ; CHECK: call double @atanh(double %conv) 111 } 112 define float @cbrt_test(float %f) { 113 %conv = fpext float %f to double 114 %call = call double @cbrt(double %conv) 115 %conv1 = fptrunc double %call to float 116 ret float %conv1 117 ; CHECK-LABEL: cbrt_test 118 ; CHECK: call float @cbrtf(float %f) 119 } 120 121 define double @cbrt_test2(float %f) { 122 %conv = fpext float %f to double 123 %call = call double @cbrt(double %conv) 124 ret double %call 125 ; CHECK-LABEL: cbrt_test2 126 ; CHECK: call double @cbrt(double %conv) 127 } 128 define float @exp_test(float %f) { 129 %conv = fpext float %f to double 130 %call = call double @exp(double %conv) 131 %conv1 = fptrunc double %call to float 132 ret float %conv1 133 ; CHECK-LABEL: exp_test 134 ; CHECK: call float @expf(float %f) 135 } 136 137 define double @exp_test2(float %f) { 138 %conv = fpext float %f to double 139 %call = call double @exp(double %conv) 140 ret double %call 141 ; CHECK-LABEL: exp_test2 142 ; CHECK: call double @exp(double %conv) 143 } 144 define float @expm1_test(float %f) { 145 %conv = fpext float %f to double 146 %call = call double @expm1(double %conv) 147 %conv1 = fptrunc double %call to float 148 ret float %conv1 149 ; CHECK-LABEL: expm1_test 150 ; CHECK: call float @expm1f(float %f) 151 } 152 153 define double @expm1_test2(float %f) { 154 %conv = fpext float %f to double 155 %call = call double @expm1(double %conv) 156 ret double %call 157 ; CHECK-LABEL: expm1_test2 158 ; CHECK: call double @expm1(double %conv) 159 } 160 define float @exp10_test(float %f) { 161 %conv = fpext float %f to double 162 %call = call double @exp10(double %conv) 163 %conv1 = fptrunc double %call to float 164 ret float %conv1 165 ; CHECK-LABEL: exp10_test 166 ; CHECK: call double @exp10(double %conv) 167 } 168 169 define double @exp10_test2(float %f) { 170 %conv = fpext float %f to double 171 %call = call double @exp10(double %conv) 172 ret double %call 173 ; CHECK-LABEL: exp10_test2 174 ; CHECK: call double @exp10(double %conv) 175 } 176 define float @log_test(float %f) { 177 %conv = fpext float %f to double 178 %call = call double @log(double %conv) 179 %conv1 = fptrunc double %call to float 180 ret float %conv1 181 ; CHECK-LABEL: log_test 182 ; CHECK: call float @logf(float %f) 183 } 184 185 define double @log_test2(float %f) { 186 %conv = fpext float %f to double 187 %call = call double @log(double %conv) 188 ret double %call 189 ; CHECK-LABEL: log_test2 190 ; CHECK: call double @log(double %conv) 191 } 192 define float @log10_test(float %f) { 193 %conv = fpext float %f to double 194 %call = call double @log10(double %conv) 195 %conv1 = fptrunc double %call to float 196 ret float %conv1 197 ; CHECK-LABEL: log10_test 198 ; CHECK: call float @log10f(float %f) 199 } 200 201 define double @log10_test2(float %f) { 202 %conv = fpext float %f to double 203 %call = call double @log10(double %conv) 204 ret double %call 205 ; CHECK-LABEL: log10_test2 206 ; CHECK: call double @log10(double %conv) 207 } 208 define float @log1p_test(float %f) { 209 %conv = fpext float %f to double 210 %call = call double @log1p(double %conv) 211 %conv1 = fptrunc double %call to float 212 ret float %conv1 213 ; CHECK-LABEL: log1p_test 214 ; CHECK: call float @log1pf(float %f) 215 } 216 217 define double @log1p_test2(float %f) { 218 %conv = fpext float %f to double 219 %call = call double @log1p(double %conv) 220 ret double %call 221 ; CHECK-LABEL: log1p_test2 222 ; CHECK: call double @log1p(double %conv) 223 } 224 define float @log2_test(float %f) { 225 %conv = fpext float %f to double 226 %call = call double @log2(double %conv) 227 %conv1 = fptrunc double %call to float 228 ret float %conv1 229 ; CHECK-LABEL: log2_test 230 ; CHECK: call float @log2f(float %f) 231 } 232 233 define double @log2_test2(float %f) { 234 %conv = fpext float %f to double 235 %call = call double @log2(double %conv) 236 ret double %call 237 ; CHECK-LABEL: log2_test2 238 ; CHECK: call double @log2(double %conv) 239 } 240 define float @logb_test(float %f) { 241 %conv = fpext float %f to double 242 %call = call double @logb(double %conv) 243 %conv1 = fptrunc double %call to float 244 ret float %conv1 245 ; CHECK-LABEL: logb_test 246 ; CHECK: call float @logbf(float %f) 247 } 248 249 define double @logb_test2(float %f) { 250 %conv = fpext float %f to double 251 %call = call double @logb(double %conv) 252 ret double %call 253 ; CHECK-LABEL: logb_test2 254 ; CHECK: call double @logb(double %conv) 255 } 256 define float @sin_test(float %f) { 257 %conv = fpext float %f to double 258 %call = call double @sin(double %conv) 259 %conv1 = fptrunc double %call to float 260 ret float %conv1 261 ; CHECK-LABEL: sin_test 262 ; CHECK: call float @sinf(float %f) 263 } 264 265 define double @sin_test2(float %f) { 266 %conv = fpext float %f to double 267 %call = call double @sin(double %conv) 268 ret double %call 269 ; CHECK-LABEL: sin_test2 270 ; CHECK: call double @sin(double %conv) 271 } 272 273 define float @sqrt_test(float %f) { 274 %conv = fpext float %f to double 275 %call = call double @sqrt(double %conv) 276 %conv1 = fptrunc double %call to float 277 ret float %conv1 278 ; CHECK-LABEL: sqrt_test 279 ; CHECK: call float @sqrtf(float %f) 280 } 281 282 define double @sqrt_test2(float %f) { 283 %conv = fpext float %f to double 284 %call = call double @sqrt(double %conv) 285 ret double %call 286 ; CHECK-LABEL: sqrt_test2 287 ; CHECK: call double @sqrt(double %conv) 288 } 289 290 define float @sqrt_int_test(float %f) { 291 %conv = fpext float %f to double 292 %call = call double @llvm.sqrt.f64(double %conv) 293 %conv1 = fptrunc double %call to float 294 ret float %conv1 295 ; CHECK-LABEL: sqrt_int_test 296 ; CHECK: call float @llvm.sqrt.f32(float %f) 297 } 298 299 define double @sqrt_int_test2(float %f) { 300 %conv = fpext float %f to double 301 %call = call double @llvm.sqrt.f64(double %conv) 302 ret double %call 303 ; CHECK-LABEL: sqrt_int_test2 304 ; CHECK: call double @llvm.sqrt.f64(double %conv) 305 } 306 307 define float @tan_test(float %f) { 308 %conv = fpext float %f to double 309 %call = call double @tan(double %conv) 310 %conv1 = fptrunc double %call to float 311 ret float %conv1 312 ; CHECK-LABEL: tan_test 313 ; CHECK: call float @tanf(float %f) 314 } 315 316 define double @tan_test2(float %f) { 317 %conv = fpext float %f to double 318 %call = call double @tan(double %conv) 319 ret double %call 320 ; CHECK-LABEL: tan_test2 321 ; CHECK: call double @tan(double %conv) 322 } 323 define float @tanh_test(float %f) { 324 %conv = fpext float %f to double 325 %call = call double @tanh(double %conv) 326 %conv1 = fptrunc double %call to float 327 ret float %conv1 328 ; CHECK-LABEL: tanh_test 329 ; CHECK: call float @tanhf(float %f) 330 } 331 332 define double @tanh_test2(float %f) { 333 %conv = fpext float %f to double 334 %call = call double @tanh(double %conv) 335 ret double %call 336 ; CHECK-LABEL: tanh_test2 337 ; CHECK: call double @tanh(double %conv) 338 } 339 340 declare double @tanh(double) #1 341 declare double @tan(double) #1 342 343 ; sqrt is a special case: the shrinking optimization 344 ; is valid even without unsafe-fp-math. 345 declare double @sqrt(double) 346 declare double @llvm.sqrt.f64(double) 347 348 declare double @sin(double) #1 349 declare double @log2(double) #1 350 declare double @log1p(double) #1 351 declare double @log10(double) #1 352 declare double @log(double) #1 353 declare double @logb(double) #1 354 declare double @exp10(double) #1 355 declare double @expm1(double) #1 356 declare double @exp(double) #1 357 declare double @cbrt(double) #1 358 declare double @atanh(double) #1 359 declare double @atan(double) #1 360 declare double @acos(double) #1 361 declare double @acosh(double) #1 362 declare double @asin(double) #1 363 declare double @asinh(double) #1 364 365 attributes #1 = { "unsafe-fp-math"="true" } 366 367