Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt < %s -instcombine -S | FileCheck %s
      2 
      3 ; Make sure all library calls are eliminated when the input is known positive.
      4 
      5 declare float @fabsf(float)
      6 declare double @fabs(double)
      7 declare fp128 @fabsl(fp128)
      8 
      9 define float @square_fabs_call_f32(float %x) {
     10   %mul = fmul float %x, %x
     11   %fabsf = tail call float @fabsf(float %mul)
     12   ret float %fabsf
     13 
     14 ; CHECK-LABEL: square_fabs_call_f32(
     15 ; CHECK-NEXT: %mul = fmul float %x, %x
     16 ; CHECK-NEXT: ret float %mul
     17 }
     18 
     19 define double @square_fabs_call_f64(double %x) {
     20   %mul = fmul double %x, %x
     21   %fabs = tail call double @fabs(double %mul)
     22   ret double %fabs
     23 
     24 ; CHECK-LABEL: square_fabs_call_f64(
     25 ; CHECK-NEXT: %mul = fmul double %x, %x
     26 ; CHECK-NEXT: ret double %mul
     27 }
     28 
     29 define fp128 @square_fabs_call_f128(fp128 %x) {
     30   %mul = fmul fp128 %x, %x
     31   %fabsl = tail call fp128 @fabsl(fp128 %mul)
     32   ret fp128 %fabsl
     33 
     34 ; CHECK-LABEL: square_fabs_call_f128(
     35 ; CHECK-NEXT: %mul = fmul fp128 %x, %x
     36 ; CHECK-NEXT: ret fp128 %mul
     37 }
     38 
     39 ; Make sure all intrinsic calls are eliminated when the input is known positive.
     40 
     41 declare float @llvm.fabs.f32(float)
     42 declare double @llvm.fabs.f64(double)
     43 declare fp128 @llvm.fabs.f128(fp128)
     44 
     45 define float @square_fabs_intrinsic_f32(float %x) {
     46   %mul = fmul float %x, %x
     47   %fabsf = tail call float @llvm.fabs.f32(float %mul)
     48   ret float %fabsf
     49 
     50 ; CHECK-LABEL: square_fabs_intrinsic_f32(
     51 ; CHECK-NEXT: %mul = fmul float %x, %x
     52 ; CHECK-NEXT: ret float %mul
     53 }
     54 
     55 define double @square_fabs_intrinsic_f64(double %x) {
     56   %mul = fmul double %x, %x
     57   %fabs = tail call double @llvm.fabs.f64(double %mul)
     58   ret double %fabs
     59 
     60 ; CHECK-LABEL: square_fabs_intrinsic_f64(
     61 ; CHECK-NEXT: %mul = fmul double %x, %x
     62 ; CHECK-NEXT: ret double %mul
     63 }
     64 
     65 define fp128 @square_fabs_intrinsic_f128(fp128 %x) {
     66   %mul = fmul fp128 %x, %x
     67   %fabsl = tail call fp128 @llvm.fabs.f128(fp128 %mul)
     68   ret fp128 %fabsl
     69 
     70 ; CHECK-LABEL: square_fabs_intrinsic_f128(
     71 ; CHECK-NEXT: %mul = fmul fp128 %x, %x
     72 ; CHECK-NEXT: ret fp128 %mul
     73 }
     74 
     75 ; Shrinking a library call to a smaller type should not be inhibited by nor inhibit the square optimization.
     76 
     77 define float @square_fabs_shrink_call1(float %x) {
     78   %ext = fpext float %x to double
     79   %sq = fmul double %ext, %ext
     80   %fabs = call double @fabs(double %sq)
     81   %trunc = fptrunc double %fabs to float
     82   ret float %trunc
     83 
     84 ; CHECK-LABEL: square_fabs_shrink_call1(
     85 ; CHECK-NEXT: %trunc = fmul float %x, %x
     86 ; CHECK-NEXT: ret float %trunc
     87 }
     88 
     89 define float @square_fabs_shrink_call2(float %x) {
     90   %sq = fmul float %x, %x
     91   %ext = fpext float %sq to double
     92   %fabs = call double @fabs(double %ext)
     93   %trunc = fptrunc double %fabs to float
     94   ret float %trunc
     95 
     96 ; CHECK-LABEL: square_fabs_shrink_call2(
     97 ; CHECK-NEXT: %sq = fmul float %x, %x
     98 ; CHECK-NEXT: ret float %sq
     99 }
    100 
    101