Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple x86_64-unknown-unknown -o - | FileCheck %s --check-prefix=X86
      2 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s --check-prefix=X86
      3 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s --check-prefix=X86
      4 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s --check-prefix=PPC
      5 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARM
      6 // RUN: %clang_cc1 %s -O1 -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K
      7 
      8 float _Complex add_float_rr(float a, float b) {
      9   // X86-LABEL: @add_float_rr(
     10   // X86: fadd
     11   // X86-NOT: fadd
     12   // X86: ret
     13   return a + b;
     14 }
     15 float _Complex add_float_cr(float _Complex a, float b) {
     16   // X86-LABEL: @add_float_cr(
     17   // X86: fadd
     18   // X86-NOT: fadd
     19   // X86: ret
     20   return a + b;
     21 }
     22 float _Complex add_float_rc(float a, float _Complex b) {
     23   // X86-LABEL: @add_float_rc(
     24   // X86: fadd
     25   // X86-NOT: fadd
     26   // X86: ret
     27   return a + b;
     28 }
     29 float _Complex add_float_cc(float _Complex a, float _Complex b) {
     30   // X86-LABEL: @add_float_cc(
     31   // X86: fadd
     32   // X86: fadd
     33   // X86-NOT: fadd
     34   // X86: ret
     35   return a + b;
     36 }
     37 
     38 float _Complex sub_float_rr(float a, float b) {
     39   // X86-LABEL: @sub_float_rr(
     40   // X86: fsub
     41   // X86-NOT: fsub
     42   // X86: ret
     43   return a - b;
     44 }
     45 float _Complex sub_float_cr(float _Complex a, float b) {
     46   // X86-LABEL: @sub_float_cr(
     47   // X86: fsub
     48   // X86-NOT: fsub
     49   // X86: ret
     50   return a - b;
     51 }
     52 float _Complex sub_float_rc(float a, float _Complex b) {
     53   // X86-LABEL: @sub_float_rc(
     54   // X86: fsub
     55   // X86: fsub float -0.{{0+}}e+00,
     56   // X86-NOT: fsub
     57   // X86: ret
     58   return a - b;
     59 }
     60 float _Complex sub_float_cc(float _Complex a, float _Complex b) {
     61   // X86-LABEL: @sub_float_cc(
     62   // X86: fsub
     63   // X86: fsub
     64   // X86-NOT: fsub
     65   // X86: ret
     66   return a - b;
     67 }
     68 
     69 float _Complex mul_float_rr(float a, float b) {
     70   // X86-LABEL: @mul_float_rr(
     71   // X86: fmul
     72   // X86-NOT: fmul
     73   // X86: ret
     74   return a * b;
     75 }
     76 float _Complex mul_float_cr(float _Complex a, float b) {
     77   // X86-LABEL: @mul_float_cr(
     78   // X86: fmul
     79   // X86: fmul
     80   // X86-NOT: fmul
     81   // X86: ret
     82   return a * b;
     83 }
     84 float _Complex mul_float_rc(float a, float _Complex b) {
     85   // X86-LABEL: @mul_float_rc(
     86   // X86: fmul
     87   // X86: fmul
     88   // X86-NOT: fmul
     89   // X86: ret
     90   return a * b;
     91 }
     92 float _Complex mul_float_cc(float _Complex a, float _Complex b) {
     93   // X86-LABEL: @mul_float_cc(
     94   // X86: %[[AC:[^ ]+]] = fmul
     95   // X86: %[[BD:[^ ]+]] = fmul
     96   // X86: %[[AD:[^ ]+]] = fmul
     97   // X86: %[[BC:[^ ]+]] = fmul
     98   // X86: %[[RR:[^ ]+]] = fsub float %[[AC]], %[[BD]]
     99   // X86: %[[RI:[^ ]+]] = fadd float
    100   // X86-DAG: %[[AD]]
    101   // X86-DAG: ,
    102   // X86-DAG: %[[BC]]
    103   // X86: fcmp uno float %[[RR]]
    104   // X86: fcmp uno float %[[RI]]
    105   // X86: call {{.*}} @__mulsc3(
    106   // X86: ret
    107   return a * b;
    108 }
    109 
    110 float _Complex div_float_rr(float a, float b) {
    111   // X86-LABEL: @div_float_rr(
    112   // X86: fdiv
    113   // X86-NOT: fdiv
    114   // X86: ret
    115   return a / b;
    116 }
    117 float _Complex div_float_cr(float _Complex a, float b) {
    118   // X86-LABEL: @div_float_cr(
    119   // X86: fdiv
    120   // X86: fdiv
    121   // X86-NOT: fdiv
    122   // X86: ret
    123   return a / b;
    124 }
    125 float _Complex div_float_rc(float a, float _Complex b) {
    126   // X86-LABEL: @div_float_rc(
    127   // X86-NOT: fdiv
    128   // X86: call {{.*}} @__divsc3(
    129   // X86: ret
    130   return a / b;
    131 }
    132 float _Complex div_float_cc(float _Complex a, float _Complex b) {
    133   // X86-LABEL: @div_float_cc(
    134   // X86-NOT: fdiv
    135   // X86: call {{.*}} @__divsc3(
    136   // X86: ret
    137   return a / b;
    138 }
    139 
    140 double _Complex add_double_rr(double a, double b) {
    141   // X86-LABEL: @add_double_rr(
    142   // X86: fadd
    143   // X86-NOT: fadd
    144   // X86: ret
    145   return a + b;
    146 }
    147 double _Complex add_double_cr(double _Complex a, double b) {
    148   // X86-LABEL: @add_double_cr(
    149   // X86: fadd
    150   // X86-NOT: fadd
    151   // X86: ret
    152   return a + b;
    153 }
    154 double _Complex add_double_rc(double a, double _Complex b) {
    155   // X86-LABEL: @add_double_rc(
    156   // X86: fadd
    157   // X86-NOT: fadd
    158   // X86: ret
    159   return a + b;
    160 }
    161 double _Complex add_double_cc(double _Complex a, double _Complex b) {
    162   // X86-LABEL: @add_double_cc(
    163   // X86: fadd
    164   // X86: fadd
    165   // X86-NOT: fadd
    166   // X86: ret
    167   return a + b;
    168 }
    169 
    170 double _Complex sub_double_rr(double a, double b) {
    171   // X86-LABEL: @sub_double_rr(
    172   // X86: fsub
    173   // X86-NOT: fsub
    174   // X86: ret
    175   return a - b;
    176 }
    177 double _Complex sub_double_cr(double _Complex a, double b) {
    178   // X86-LABEL: @sub_double_cr(
    179   // X86: fsub
    180   // X86-NOT: fsub
    181   // X86: ret
    182   return a - b;
    183 }
    184 double _Complex sub_double_rc(double a, double _Complex b) {
    185   // X86-LABEL: @sub_double_rc(
    186   // X86: fsub
    187   // X86: fsub double -0.{{0+}}e+00,
    188   // X86-NOT: fsub
    189   // X86: ret
    190   return a - b;
    191 }
    192 double _Complex sub_double_cc(double _Complex a, double _Complex b) {
    193   // X86-LABEL: @sub_double_cc(
    194   // X86: fsub
    195   // X86: fsub
    196   // X86-NOT: fsub
    197   // X86: ret
    198   return a - b;
    199 }
    200 
    201 double _Complex mul_double_rr(double a, double b) {
    202   // X86-LABEL: @mul_double_rr(
    203   // X86: fmul
    204   // X86-NOT: fmul
    205   // X86: ret
    206   return a * b;
    207 }
    208 double _Complex mul_double_cr(double _Complex a, double b) {
    209   // X86-LABEL: @mul_double_cr(
    210   // X86: fmul
    211   // X86: fmul
    212   // X86-NOT: fmul
    213   // X86: ret
    214   return a * b;
    215 }
    216 double _Complex mul_double_rc(double a, double _Complex b) {
    217   // X86-LABEL: @mul_double_rc(
    218   // X86: fmul
    219   // X86: fmul
    220   // X86-NOT: fmul
    221   // X86: ret
    222   return a * b;
    223 }
    224 double _Complex mul_double_cc(double _Complex a, double _Complex b) {
    225   // X86-LABEL: @mul_double_cc(
    226   // X86: %[[AC:[^ ]+]] = fmul
    227   // X86: %[[BD:[^ ]+]] = fmul
    228   // X86: %[[AD:[^ ]+]] = fmul
    229   // X86: %[[BC:[^ ]+]] = fmul
    230   // X86: %[[RR:[^ ]+]] = fsub double %[[AC]], %[[BD]]
    231   // X86: %[[RI:[^ ]+]] = fadd double
    232   // X86-DAG: %[[AD]]
    233   // X86-DAG: ,
    234   // X86-DAG: %[[BC]]
    235   // X86: fcmp uno double %[[RR]]
    236   // X86: fcmp uno double %[[RI]]
    237   // X86: call {{.*}} @__muldc3(
    238   // X86: ret
    239   return a * b;
    240 }
    241 
    242 double _Complex div_double_rr(double a, double b) {
    243   // X86-LABEL: @div_double_rr(
    244   // X86: fdiv
    245   // X86-NOT: fdiv
    246   // X86: ret
    247   return a / b;
    248 }
    249 double _Complex div_double_cr(double _Complex a, double b) {
    250   // X86-LABEL: @div_double_cr(
    251   // X86: fdiv
    252   // X86: fdiv
    253   // X86-NOT: fdiv
    254   // X86: ret
    255   return a / b;
    256 }
    257 double _Complex div_double_rc(double a, double _Complex b) {
    258   // X86-LABEL: @div_double_rc(
    259   // X86-NOT: fdiv
    260   // X86: call {{.*}} @__divdc3(
    261   // X86: ret
    262   return a / b;
    263 }
    264 double _Complex div_double_cc(double _Complex a, double _Complex b) {
    265   // X86-LABEL: @div_double_cc(
    266   // X86-NOT: fdiv
    267   // X86: call {{.*}} @__divdc3(
    268   // X86: ret
    269   return a / b;
    270 }
    271 
    272 long double _Complex add_long_double_rr(long double a, long double b) {
    273   // X86-LABEL: @add_long_double_rr(
    274   // X86: fadd
    275   // X86-NOT: fadd
    276   // X86: ret
    277   return a + b;
    278 }
    279 long double _Complex add_long_double_cr(long double _Complex a, long double b) {
    280   // X86-LABEL: @add_long_double_cr(
    281   // X86: fadd
    282   // X86-NOT: fadd
    283   // X86: ret
    284   return a + b;
    285 }
    286 long double _Complex add_long_double_rc(long double a, long double _Complex b) {
    287   // X86-LABEL: @add_long_double_rc(
    288   // X86: fadd
    289   // X86-NOT: fadd
    290   // X86: ret
    291   return a + b;
    292 }
    293 long double _Complex add_long_double_cc(long double _Complex a, long double _Complex b) {
    294   // X86-LABEL: @add_long_double_cc(
    295   // X86: fadd
    296   // X86: fadd
    297   // X86-NOT: fadd
    298   // X86: ret
    299   return a + b;
    300 }
    301 
    302 long double _Complex sub_long_double_rr(long double a, long double b) {
    303   // X86-LABEL: @sub_long_double_rr(
    304   // X86: fsub
    305   // X86-NOT: fsub
    306   // X86: ret
    307   return a - b;
    308 }
    309 long double _Complex sub_long_double_cr(long double _Complex a, long double b) {
    310   // X86-LABEL: @sub_long_double_cr(
    311   // X86: fsub
    312   // X86-NOT: fsub
    313   // X86: ret
    314   return a - b;
    315 }
    316 long double _Complex sub_long_double_rc(long double a, long double _Complex b) {
    317   // X86-LABEL: @sub_long_double_rc(
    318   // X86: fsub
    319   // X86: fsub x86_fp80 0xK8{{0+}},
    320   // X86-NOT: fsub
    321   // X86: ret
    322   return a - b;
    323 }
    324 long double _Complex sub_long_double_cc(long double _Complex a, long double _Complex b) {
    325   // X86-LABEL: @sub_long_double_cc(
    326   // X86: fsub
    327   // X86: fsub
    328   // X86-NOT: fsub
    329   // X86: ret
    330   return a - b;
    331 }
    332 
    333 long double _Complex mul_long_double_rr(long double a, long double b) {
    334   // X86-LABEL: @mul_long_double_rr(
    335   // X86: fmul
    336   // X86-NOT: fmul
    337   // X86: ret
    338   return a * b;
    339 }
    340 long double _Complex mul_long_double_cr(long double _Complex a, long double b) {
    341   // X86-LABEL: @mul_long_double_cr(
    342   // X86: fmul
    343   // X86: fmul
    344   // X86-NOT: fmul
    345   // X86: ret
    346   return a * b;
    347 }
    348 long double _Complex mul_long_double_rc(long double a, long double _Complex b) {
    349   // X86-LABEL: @mul_long_double_rc(
    350   // X86: fmul
    351   // X86: fmul
    352   // X86-NOT: fmul
    353   // X86: ret
    354   return a * b;
    355 }
    356 long double _Complex mul_long_double_cc(long double _Complex a, long double _Complex b) {
    357   // X86-LABEL: @mul_long_double_cc(
    358   // X86: %[[AC:[^ ]+]] = fmul
    359   // X86: %[[BD:[^ ]+]] = fmul
    360   // X86: %[[AD:[^ ]+]] = fmul
    361   // X86: %[[BC:[^ ]+]] = fmul
    362   // X86: %[[RR:[^ ]+]] = fsub x86_fp80 %[[AC]], %[[BD]]
    363   // X86: %[[RI:[^ ]+]] = fadd x86_fp80
    364   // X86-DAG: %[[AD]]
    365   // X86-DAG: ,
    366   // X86-DAG: %[[BC]]
    367   // X86: fcmp uno x86_fp80 %[[RR]]
    368   // X86: fcmp uno x86_fp80 %[[RI]]
    369   // X86: call {{.*}} @__mulxc3(
    370   // X86: ret
    371   // PPC-LABEL: @mul_long_double_cc(
    372   // PPC: %[[AC:[^ ]+]] = fmul
    373   // PPC: %[[BD:[^ ]+]] = fmul
    374   // PPC: %[[AD:[^ ]+]] = fmul
    375   // PPC: %[[BC:[^ ]+]] = fmul
    376   // PPC: %[[RR:[^ ]+]] = fsub ppc_fp128 %[[AC]], %[[BD]]
    377   // PPC: %[[RI:[^ ]+]] = fadd ppc_fp128
    378   // PPC-DAG: %[[AD]]
    379   // PPC-DAG: ,
    380   // PPC-DAG: %[[BC]]
    381   // PPC: fcmp uno ppc_fp128 %[[RR]]
    382   // PPC: fcmp uno ppc_fp128 %[[RI]]
    383   // PPC: call {{.*}} @__multc3(
    384   // PPC: ret
    385   return a * b;
    386 }
    387 
    388 long double _Complex div_long_double_rr(long double a, long double b) {
    389   // X86-LABEL: @div_long_double_rr(
    390   // X86: fdiv
    391   // X86-NOT: fdiv
    392   // X86: ret
    393   return a / b;
    394 }
    395 long double _Complex div_long_double_cr(long double _Complex a, long double b) {
    396   // X86-LABEL: @div_long_double_cr(
    397   // X86: fdiv
    398   // X86: fdiv
    399   // X86-NOT: fdiv
    400   // X86: ret
    401   return a / b;
    402 }
    403 long double _Complex div_long_double_rc(long double a, long double _Complex b) {
    404   // X86-LABEL: @div_long_double_rc(
    405   // X86-NOT: fdiv
    406   // X86: call {{.*}} @__divxc3(
    407   // X86: ret
    408   // PPC-LABEL: @div_long_double_rc(
    409   // PPC-NOT: fdiv
    410   // PPC: call {{.*}} @__divtc3(
    411   // PPC: ret
    412   return a / b;
    413 }
    414 long double _Complex div_long_double_cc(long double _Complex a, long double _Complex b) {
    415   // X86-LABEL: @div_long_double_cc(
    416   // X86-NOT: fdiv
    417   // X86: call {{.*}} @__divxc3(
    418   // X86: ret
    419   // PPC-LABEL: @div_long_double_cc(
    420   // PPC-NOT: fdiv
    421   // PPC: call {{.*}} @__divtc3(
    422   // PPC: ret
    423   return a / b;
    424 }
    425 
    426 // Comparison operators don't rely on library calls or have interseting math
    427 // properties, but test that mixed types work correctly here.
    428 _Bool eq_float_cr(float _Complex a, float b) {
    429   // X86-LABEL: @eq_float_cr(
    430   // X86: fcmp oeq
    431   // X86: fcmp oeq
    432   // X86: and i1
    433   // X86: ret
    434   return a == b;
    435 }
    436 _Bool eq_float_rc(float a, float _Complex b) {
    437   // X86-LABEL: @eq_float_rc(
    438   // X86: fcmp oeq
    439   // X86: fcmp oeq
    440   // X86: and i1
    441   // X86: ret
    442   return a == b;
    443 }
    444 _Bool eq_float_cc(float _Complex a, float _Complex b) {
    445   // X86-LABEL: @eq_float_cc(
    446   // X86: fcmp oeq
    447   // X86: fcmp oeq
    448   // X86: and i1
    449   // X86: ret
    450   return a == b;
    451 }
    452 _Bool ne_float_cr(float _Complex a, float b) {
    453   // X86-LABEL: @ne_float_cr(
    454   // X86: fcmp une
    455   // X86: fcmp une
    456   // X86: or i1
    457   // X86: ret
    458   return a != b;
    459 }
    460 _Bool ne_float_rc(float a, float _Complex b) {
    461   // X86-LABEL: @ne_float_rc(
    462   // X86: fcmp une
    463   // X86: fcmp une
    464   // X86: or i1
    465   // X86: ret
    466   return a != b;
    467 }
    468 _Bool ne_float_cc(float _Complex a, float _Complex b) {
    469   // X86-LABEL: @ne_float_cc(
    470   // X86: fcmp une
    471   // X86: fcmp une
    472   // X86: or i1
    473   // X86: ret
    474   return a != b;
    475 }
    476 
    477 // Check that the libcall will obtain proper calling convention on ARM
    478 _Complex double foo(_Complex double a, _Complex double b) {
    479   // ARM-LABEL: @foo(
    480   // ARM: call arm_aapcscc { double, double } @__muldc3
    481 
    482   // ARM7K-LABEL: @foo(
    483   // ARM7K: call { double, double } @__muldc3
    484   return a*b;
    485 }
    486