1; RUN: opt < %s -instcombine -S | FileCheck %s 2 3target 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" 4target 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 12define float @acos_test1(float %f) { 13 %conv = fpext float %f to double 14 %call = call fast double @acos(double %conv) 15 %conv1 = fptrunc double %call to float 16 ret float %conv1 17; CHECK-LABEL: acos_test1 18; CHECK: call fast float @acosf(float %f) 19} 20 21define double @acos_test2(float %f) { 22 %conv = fpext float %f to double 23 %call = call fast double @acos(double %conv) 24 ret double %call 25; CHECK-LABEL: acos_test2 26; CHECK: call fast double @acos(double %conv) 27} 28 29define float @acosh_test1(float %f) { 30 %conv = fpext float %f to double 31 %call = call fast double @acosh(double %conv) 32 %conv1 = fptrunc double %call to float 33 ret float %conv1 34; CHECK-LABEL: acosh_test1 35; CHECK: call fast float @acoshf(float %f) 36} 37 38define double @acosh_test2(float %f) { 39 %conv = fpext float %f to double 40 %call = call fast double @acosh(double %conv) 41 ret double %call 42; CHECK-LABEL: acosh_test2 43; CHECK: call fast double @acosh(double %conv) 44} 45 46define float @asin_test1(float %f) { 47 %conv = fpext float %f to double 48 %call = call fast double @asin(double %conv) 49 %conv1 = fptrunc double %call to float 50 ret float %conv1 51; CHECK-LABEL: asin_test1 52; CHECK: call fast float @asinf(float %f) 53} 54 55define double @asin_test2(float %f) { 56 %conv = fpext float %f to double 57 %call = call fast double @asin(double %conv) 58 ret double %call 59; CHECK-LABEL: asin_test2 60; CHECK: call fast double @asin(double %conv) 61} 62 63define float @asinh_test1(float %f) { 64 %conv = fpext float %f to double 65 %call = call fast double @asinh(double %conv) 66 %conv1 = fptrunc double %call to float 67 ret float %conv1 68; CHECK-LABEL: asinh_test1 69; CHECK: call fast float @asinhf(float %f) 70} 71 72define double @asinh_test2(float %f) { 73 %conv = fpext float %f to double 74 %call = call fast double @asinh(double %conv) 75 ret double %call 76; CHECK-LABEL: asinh_test2 77; CHECK: call fast double @asinh(double %conv) 78} 79 80define float @atan_test1(float %f) { 81 %conv = fpext float %f to double 82 %call = call fast double @atan(double %conv) 83 %conv1 = fptrunc double %call to float 84 ret float %conv1 85; CHECK-LABEL: atan_test1 86; CHECK: call fast float @atanf(float %f) 87} 88 89define double @atan_test2(float %f) { 90 %conv = fpext float %f to double 91 %call = call fast double @atan(double %conv) 92 ret double %call 93; CHECK-LABEL: atan_test2 94; CHECK: call fast double @atan(double %conv) 95} 96 97define float @atanh_test1(float %f) { 98 %conv = fpext float %f to double 99 %call = call fast double @atanh(double %conv) 100 %conv1 = fptrunc double %call to float 101 ret float %conv1 102; CHECK-LABEL: atanh_test1 103; CHECK: call fast float @atanhf(float %f) 104} 105 106define double @atanh_test2(float %f) { 107 %conv = fpext float %f to double 108 %call = call fast double @atanh(double %conv) 109 ret double %call 110; CHECK-LABEL: atanh_test2 111; CHECK: call fast double @atanh(double %conv) 112} 113 114define float @cbrt_test1(float %f) { 115 %conv = fpext float %f to double 116 %call = call fast double @cbrt(double %conv) 117 %conv1 = fptrunc double %call to float 118 ret float %conv1 119; CHECK-LABEL: cbrt_test1 120; CHECK: call fast float @cbrtf(float %f) 121} 122 123define double @cbrt_test2(float %f) { 124 %conv = fpext float %f to double 125 %call = call fast double @cbrt(double %conv) 126 ret double %call 127; CHECK-LABEL: cbrt_test2 128; CHECK: call fast double @cbrt(double %conv) 129} 130 131define float @exp_test1(float %f) { 132 %conv = fpext float %f to double 133 %call = call fast double @exp(double %conv) 134 %conv1 = fptrunc double %call to float 135 ret float %conv1 136; CHECK-LABEL: exp_test1 137; CHECK: call fast float @expf(float %f) 138} 139 140define double @exp_test2(float %f) { 141 %conv = fpext float %f to double 142 %call = call fast double @exp(double %conv) 143 ret double %call 144; CHECK-LABEL: exp_test2 145; CHECK: call fast double @exp(double %conv) 146} 147 148define float @expm1_test1(float %f) { 149 %conv = fpext float %f to double 150 %call = call fast double @expm1(double %conv) 151 %conv1 = fptrunc double %call to float 152 ret float %conv1 153; CHECK-LABEL: expm1_test1 154; CHECK: call fast float @expm1f(float %f) 155} 156 157define double @expm1_test2(float %f) { 158 %conv = fpext float %f to double 159 %call = call fast double @expm1(double %conv) 160 ret double %call 161; CHECK-LABEL: expm1_test2 162; CHECK: call fast double @expm1(double %conv) 163} 164 165; exp10f() doesn't exist for this triple, so it doesn't shrink. 166 167define float @exp10_test1(float %f) { 168 %conv = fpext float %f to double 169 %call = call fast double @exp10(double %conv) 170 %conv1 = fptrunc double %call to float 171 ret float %conv1 172; CHECK-LABEL: exp10_test1 173; CHECK: call fast double @exp10(double %conv) 174} 175 176define double @exp10_test2(float %f) { 177 %conv = fpext float %f to double 178 %call = call fast double @exp10(double %conv) 179 ret double %call 180; CHECK-LABEL: exp10_test2 181; CHECK: call fast double @exp10(double %conv) 182} 183 184define float @log_test1(float %f) { 185 %conv = fpext float %f to double 186 %call = call fast double @log(double %conv) 187 %conv1 = fptrunc double %call to float 188 ret float %conv1 189; CHECK-LABEL: log_test1 190; CHECK: call fast float @logf(float %f) 191} 192 193define double @log_test2(float %f) { 194 %conv = fpext float %f to double 195 %call = call fast double @log(double %conv) 196 ret double %call 197; CHECK-LABEL: log_test2 198; CHECK: call fast double @log(double %conv) 199} 200 201define float @log10_test1(float %f) { 202 %conv = fpext float %f to double 203 %call = call fast double @log10(double %conv) 204 %conv1 = fptrunc double %call to float 205 ret float %conv1 206; CHECK-LABEL: log10_test1 207; CHECK: call fast float @log10f(float %f) 208} 209 210define double @log10_test2(float %f) { 211 %conv = fpext float %f to double 212 %call = call fast double @log10(double %conv) 213 ret double %call 214; CHECK-LABEL: log10_test2 215; CHECK: call fast double @log10(double %conv) 216} 217 218define float @log1p_test1(float %f) { 219 %conv = fpext float %f to double 220 %call = call fast double @log1p(double %conv) 221 %conv1 = fptrunc double %call to float 222 ret float %conv1 223; CHECK-LABEL: log1p_test1 224; CHECK: call fast float @log1pf(float %f) 225} 226 227define double @log1p_test2(float %f) { 228 %conv = fpext float %f to double 229 %call = call fast double @log1p(double %conv) 230 ret double %call 231; CHECK-LABEL: log1p_test2 232; CHECK: call fast double @log1p(double %conv) 233} 234 235define float @log2_test1(float %f) { 236 %conv = fpext float %f to double 237 %call = call fast double @log2(double %conv) 238 %conv1 = fptrunc double %call to float 239 ret float %conv1 240; CHECK-LABEL: log2_test1 241; CHECK: call fast float @log2f(float %f) 242} 243 244define double @log2_test2(float %f) { 245 %conv = fpext float %f to double 246 %call = call fast double @log2(double %conv) 247 ret double %call 248; CHECK-LABEL: log2_test2 249; CHECK: call fast double @log2(double %conv) 250} 251 252define float @logb_test1(float %f) { 253 %conv = fpext float %f to double 254 %call = call fast double @logb(double %conv) 255 %conv1 = fptrunc double %call to float 256 ret float %conv1 257; CHECK-LABEL: logb_test1 258; CHECK: call fast float @logbf(float %f) 259} 260 261define double @logb_test2(float %f) { 262 %conv = fpext float %f to double 263 %call = call fast double @logb(double %conv) 264 ret double %call 265; CHECK-LABEL: logb_test2 266; CHECK: call fast double @logb(double %conv) 267} 268 269define float @sin_test1(float %f) { 270 %conv = fpext float %f to double 271 %call = call fast double @sin(double %conv) 272 %conv1 = fptrunc double %call to float 273 ret float %conv1 274; CHECK-LABEL: sin_test1 275; CHECK: call fast float @sinf(float %f) 276} 277 278define double @sin_test2(float %f) { 279 %conv = fpext float %f to double 280 %call = call fast double @sin(double %conv) 281 ret double %call 282; CHECK-LABEL: sin_test2 283; CHECK: call fast double @sin(double %conv) 284} 285 286define float @sqrt_test1(float %f) { 287 %conv = fpext float %f to double 288 %call = call double @sqrt(double %conv) 289 %conv1 = fptrunc double %call to float 290 ret float %conv1 291; CHECK-LABEL: sqrt_test1 292; CHECK: call float @sqrtf(float %f) 293} 294 295define double @sqrt_test2(float %f) { 296 %conv = fpext float %f to double 297 %call = call double @sqrt(double %conv) 298 ret double %call 299; CHECK-LABEL: sqrt_test2 300; CHECK: call double @sqrt(double %conv) 301} 302 303define float @sqrt_int_test1(float %f) { 304 %conv = fpext float %f to double 305 %call = call double @llvm.sqrt.f64(double %conv) 306 %conv1 = fptrunc double %call to float 307 ret float %conv1 308; CHECK-LABEL: sqrt_int_test1 309; CHECK: call float @llvm.sqrt.f32(float %f) 310} 311 312define double @sqrt_int_test2(float %f) { 313 %conv = fpext float %f to double 314 %call = call double @llvm.sqrt.f64(double %conv) 315 ret double %call 316; CHECK-LABEL: sqrt_int_test2 317; CHECK: call double @llvm.sqrt.f64(double %conv) 318} 319 320define float @tan_test1(float %f) { 321 %conv = fpext float %f to double 322 %call = call fast double @tan(double %conv) 323 %conv1 = fptrunc double %call to float 324 ret float %conv1 325; CHECK-LABEL: tan_test1 326; CHECK: call fast float @tanf(float %f) 327} 328 329define double @tan_test2(float %f) { 330 %conv = fpext float %f to double 331 %call = call fast double @tan(double %conv) 332 ret double %call 333; CHECK-LABEL: tan_test2 334; CHECK: call fast double @tan(double %conv) 335} 336define float @tanh_test1(float %f) { 337 %conv = fpext float %f to double 338 %call = call fast double @tanh(double %conv) 339 %conv1 = fptrunc double %call to float 340 ret float %conv1 341; CHECK-LABEL: tanh_test1 342; CHECK: call fast float @tanhf(float %f) 343} 344 345define double @tanh_test2(float %f) { 346 %conv = fpext float %f to double 347 %call = call fast double @tanh(double %conv) 348 ret double %call 349; CHECK-LABEL: tanh_test2 350; CHECK: call fast double @tanh(double %conv) 351} 352 353; 'arcp' on an fmax() is meaningless. This test just proves that 354; flags are propagated for shrunken *binary* double FP calls. 355define float @max1(float %a, float %b) { 356 %c = fpext float %a to double 357 %d = fpext float %b to double 358 %e = call arcp double @fmax(double %c, double %d) 359 %f = fptrunc double %e to float 360 ret float %f 361 362; CHECK-LABEL: max1( 363; CHECK-NEXT: call arcp float @fmaxf(float %a, float %b) 364; CHECK-NEXT: ret 365} 366 367; A function can have a name that matches a common libcall, 368; but with the wrong type(s). Let it be. 369 370define float @fake_fmin(float %a, float %b) { 371 %c = fpext float %a to fp128 372 %d = fpext float %b to fp128 373 %e = call fp128 @fmin(fp128 %c, fp128 %d) 374 %f = fptrunc fp128 %e to float 375 ret float %f 376 377; CHECK-LABEL: fake_fmin( 378; CHECK-NEXT: %c = fpext float %a to fp128 379; CHECK-NEXT: %d = fpext float %b to fp128 380; CHECK-NEXT: %e = call fp128 @fmin(fp128 %c, fp128 %d) 381; CHECK-NEXT: %f = fptrunc fp128 %e to float 382; CHECK-NEXT: ret float %f 383} 384 385declare fp128 @fmin(fp128, fp128) ; This is not the 'fmin' you're looking for. 386 387declare double @fmax(double, double) 388 389declare double @tanh(double) 390declare double @tan(double) 391 392; sqrt is a special case: the shrinking optimization 393; is valid even without unsafe-fp-math. 394declare double @sqrt(double) 395declare double @llvm.sqrt.f64(double) 396 397declare double @sin(double) 398declare double @log2(double) 399declare double @log1p(double) 400declare double @log10(double) 401declare double @log(double) 402declare double @logb(double) 403declare double @exp10(double) 404declare double @expm1(double) 405declare double @exp(double) 406declare double @cbrt(double) 407declare double @atanh(double) 408declare double @atan(double) 409declare double @acos(double) 410declare double @acosh(double) 411declare double @asin(double) 412declare double @asinh(double) 413 414