Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -O3 -mtriple=x86_64-pc-linux < %s | FileCheck --check-prefix=COMMON --check-prefix=NO-FMA --check-prefix=FMACALL64 --check-prefix=FMACALL32 %s
      2 ; RUN: llc -O3 -mtriple=x86_64-pc-linux -mattr=+fma < %s | FileCheck -check-prefix=COMMON --check-prefix=HAS-FMA --check-prefix=FMA64 --check-prefix=FMA32 %s
      3 
      4 ; Verify that constants aren't folded to inexact results when the rounding mode
      5 ; is unknown.
      6 ;
      7 ; double f1() {
      8 ;   // Because 0.1 cannot be represented exactly, this shouldn't be folded.
      9 ;   return 1.0/10.0;
     10 ; }
     11 ;
     12 ; CHECK-LABEL: f1
     13 ; COMMON: divsd
     14 define double @f1() {
     15 entry:
     16   %div = call double @llvm.experimental.constrained.fdiv.f64(
     17                                                double 1.000000e+00,
     18                                                double 1.000000e+01,
     19                                                metadata !"round.dynamic",
     20                                                metadata !"fpexcept.strict")
     21   ret double %div
     22 }
     23 
     24 ; Verify that 'a - 0' isn't simplified to 'a' when the rounding mode is unknown.
     25 ;
     26 ; double f2(double a) {
     27 ;   // Because the result of '0 - 0' is negative zero if rounding mode is
     28 ;   // downward, this shouldn't be simplified.
     29 ;   return a - 0;
     30 ; }
     31 ;
     32 ; CHECK-LABEL: f2
     33 ; COMMON:  subsd
     34 define double @f2(double %a) {
     35 entry:
     36   %sub = call double @llvm.experimental.constrained.fsub.f64(
     37                                                double %a,
     38                                                double 0.000000e+00,
     39                                                metadata !"round.dynamic",
     40                                                metadata !"fpexcept.strict")
     41   ret double %sub
     42 }
     43 
     44 ; Verify that '-((-a)*b)' isn't simplified to 'a*b' when the rounding mode is
     45 ; unknown.
     46 ;
     47 ; double f3(double a, double b) {
     48 ;   // Because the intermediate value involved in this calculation may require
     49 ;   // rounding, this shouldn't be simplified.
     50 ;   return -((-a)*b);
     51 ; }
     52 ;
     53 ; CHECK-LABEL: f3:
     54 ; COMMON:  subsd
     55 ; COMMON:  mulsd
     56 ; COMMON:  subsd
     57 define double @f3(double %a, double %b) {
     58 entry:
     59   %sub = call double @llvm.experimental.constrained.fsub.f64(
     60                                                double -0.000000e+00, double %a,
     61                                                metadata !"round.dynamic",
     62                                                metadata !"fpexcept.strict")
     63   %mul = call double @llvm.experimental.constrained.fmul.f64(
     64                                                double %sub, double %b,
     65                                                metadata !"round.dynamic",
     66                                                metadata !"fpexcept.strict")
     67   %ret = call double @llvm.experimental.constrained.fsub.f64(
     68                                                double -0.000000e+00,
     69                                                double %mul,
     70                                                metadata !"round.dynamic",
     71                                                metadata !"fpexcept.strict")
     72   ret double %ret
     73 }
     74 
     75 ; Verify that FP operations are not performed speculatively when FP exceptions
     76 ; are not being ignored.
     77 ;
     78 ; double f4(int n, double a) {
     79 ;   // Because a + 1 may overflow, this should not be simplified.
     80 ;   if (n > 0)
     81 ;     return a + 1.0;
     82 ;   return a;
     83 ; }
     84 ;
     85 ;
     86 ; CHECK-LABEL: f4:
     87 ; COMMON: testl
     88 ; COMMON: jle
     89 ; COMMON: addsd
     90 define double @f4(i32 %n, double %a) {
     91 entry:
     92   %cmp = icmp sgt i32 %n, 0
     93   br i1 %cmp, label %if.then, label %if.end
     94 
     95 if.then:
     96   %add = call double @llvm.experimental.constrained.fadd.f64(
     97                                                double 1.000000e+00, double %a,
     98                                                metadata !"round.dynamic",
     99                                                metadata !"fpexcept.strict")
    100   br label %if.end
    101 
    102 if.end:
    103   %a.0 = phi double [%add, %if.then], [ %a, %entry ]
    104   ret double %a.0
    105 }
    106 
    107 ; Verify that sqrt(42.0) isn't simplified when the rounding mode is unknown.
    108 ; CHECK-LABEL: f5
    109 ; COMMON:  sqrtsd
    110 define double @f5() {
    111 entry:
    112   %result = call double @llvm.experimental.constrained.sqrt.f64(double 42.0,
    113                                                metadata !"round.dynamic",
    114                                                metadata !"fpexcept.strict")
    115   ret double %result
    116 }
    117 
    118 ; Verify that pow(42.1, 3.0) isn't simplified when the rounding mode is unknown.
    119 ; CHECK-LABEL: f6
    120 ; COMMON:  pow
    121 define double @f6() {
    122 entry:
    123   %result = call double @llvm.experimental.constrained.pow.f64(double 42.1,
    124                                                double 3.0,
    125                                                metadata !"round.dynamic",
    126                                                metadata !"fpexcept.strict")
    127   ret double %result
    128 }
    129 
    130 ; Verify that powi(42.1, 3) isn't simplified when the rounding mode is unknown.
    131 ; CHECK-LABEL: f7
    132 ; COMMON:  powi
    133 define double @f7() {
    134 entry:
    135   %result = call double @llvm.experimental.constrained.powi.f64(double 42.1,
    136                                                i32 3,
    137                                                metadata !"round.dynamic",
    138                                                metadata !"fpexcept.strict")
    139   ret double %result
    140 }
    141 
    142 ; Verify that sin(42.0) isn't simplified when the rounding mode is unknown.
    143 ; CHECK-LABEL: f8
    144 ; COMMON:  sin
    145 define double @f8() {
    146 entry:
    147   %result = call double @llvm.experimental.constrained.sin.f64(double 42.0,
    148                                                metadata !"round.dynamic",
    149                                                metadata !"fpexcept.strict")
    150   ret double %result
    151 }
    152 
    153 ; Verify that cos(42.0) isn't simplified when the rounding mode is unknown.
    154 ; CHECK-LABEL: f9
    155 ; COMMON:  cos
    156 define double @f9() {
    157 entry:
    158   %result = call double @llvm.experimental.constrained.cos.f64(double 42.0,
    159                                                metadata !"round.dynamic",
    160                                                metadata !"fpexcept.strict")
    161   ret double %result
    162 }
    163 
    164 ; Verify that exp(42.0) isn't simplified when the rounding mode is unknown.
    165 ; CHECK-LABEL: f10
    166 ; COMMON:  exp
    167 define double @f10() {
    168 entry:
    169   %result = call double @llvm.experimental.constrained.exp.f64(double 42.0,
    170                                                metadata !"round.dynamic",
    171                                                metadata !"fpexcept.strict")
    172   ret double %result
    173 }
    174 
    175 ; Verify that exp2(42.1) isn't simplified when the rounding mode is unknown.
    176 ; CHECK-LABEL: f11
    177 ; COMMON:  exp2
    178 define double @f11() {
    179 entry:
    180   %result = call double @llvm.experimental.constrained.exp2.f64(double 42.1,
    181                                                metadata !"round.dynamic",
    182                                                metadata !"fpexcept.strict")
    183   ret double %result
    184 }
    185 
    186 ; Verify that log(42.0) isn't simplified when the rounding mode is unknown.
    187 ; CHECK-LABEL: f12
    188 ; COMMON:  log
    189 define double @f12() {
    190 entry:
    191   %result = call double @llvm.experimental.constrained.log.f64(double 42.0,
    192                                                metadata !"round.dynamic",
    193                                                metadata !"fpexcept.strict")
    194   ret double %result
    195 }
    196 
    197 ; Verify that log10(42.0) isn't simplified when the rounding mode is unknown.
    198 ; CHECK-LABEL: f13
    199 ; COMMON:  log10
    200 define double @f13() {
    201 entry:
    202   %result = call double @llvm.experimental.constrained.log10.f64(double 42.0,
    203                                                metadata !"round.dynamic",
    204                                                metadata !"fpexcept.strict")
    205   ret double %result
    206 }
    207 
    208 ; Verify that log2(42.0) isn't simplified when the rounding mode is unknown.
    209 ; CHECK-LABEL: f14
    210 ; COMMON:  log2
    211 define double @f14() {
    212 entry:
    213   %result = call double @llvm.experimental.constrained.log2.f64(double 42.0,
    214                                                metadata !"round.dynamic",
    215                                                metadata !"fpexcept.strict")
    216   ret double %result
    217 }
    218 
    219 ; Verify that rint(42.1) isn't simplified when the rounding mode is unknown.
    220 ; CHECK-LABEL: f15
    221 ; NO-FMA:  rint
    222 ; HAS-FMA: vroundsd
    223 define double @f15() {
    224 entry:
    225   %result = call double @llvm.experimental.constrained.rint.f64(double 42.1,
    226                                                metadata !"round.dynamic",
    227                                                metadata !"fpexcept.strict")
    228   ret double %result
    229 }
    230 
    231 ; Verify that nearbyint(42.1) isn't simplified when the rounding mode is
    232 ; unknown.
    233 ; CHECK-LABEL: f16
    234 ; NO-FMA:  nearbyint
    235 ; HAS-FMA: vroundsd
    236 define double @f16() {
    237 entry:
    238   %result = call double @llvm.experimental.constrained.nearbyint.f64(
    239                                                double 42.1,
    240                                                metadata !"round.dynamic",
    241                                                metadata !"fpexcept.strict")
    242   ret double %result
    243 }
    244 
    245 ; Verify that fma(3.5) isn't simplified when the rounding mode is
    246 ; unknown.
    247 ; CHECK-LABEL: f17
    248 ; FMACALL32: jmp fmaf  # TAILCALL
    249 ; FMA32: vfmadd213ss
    250 define float @f17() {
    251 entry:
    252   %result = call float @llvm.experimental.constrained.fma.f32(
    253                                                float 3.5,
    254                                                float 3.5,
    255                                                float 3.5,
    256                                                metadata !"round.dynamic",
    257                                                metadata !"fpexcept.strict")
    258   ret float %result
    259 }
    260 
    261 ; Verify that fma(42.1) isn't simplified when the rounding mode is
    262 ; unknown.
    263 ; CHECK-LABEL: f18
    264 ; FMACALL64: jmp fma  # TAILCALL
    265 ; FMA64: vfmadd213sd
    266 define double @f18() {
    267 entry:
    268   %result = call double @llvm.experimental.constrained.fma.f64(
    269                                                double 42.1,
    270                                                double 42.1,
    271                                                double 42.1,
    272                                                metadata !"round.dynamic",
    273                                                metadata !"fpexcept.strict")
    274   ret double %result
    275 }
    276 
    277 @llvm.fp.env = thread_local global i8 zeroinitializer, section "llvm.metadata"
    278 declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
    279 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
    280 declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
    281 declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
    282 declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata)
    283 declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
    284 declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
    285 declare double @llvm.experimental.constrained.sin.f64(double, metadata, metadata)
    286 declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
    287 declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata)
    288 declare double @llvm.experimental.constrained.exp2.f64(double, metadata, metadata)
    289 declare double @llvm.experimental.constrained.log.f64(double, metadata, metadata)
    290 declare double @llvm.experimental.constrained.log10.f64(double, metadata, metadata)
    291 declare double @llvm.experimental.constrained.log2.f64(double, metadata, metadata)
    292 declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata)
    293 declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
    294 declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata)
    295 declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata)
    296