Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -mtriple=arm64-linux-gnu -verify-machineinstrs -mcpu=cyclone -aarch64-atomic-cfg-tidy=0 < %s | FileCheck %s
      2 
      3 @lhs = global fp128 zeroinitializer, align 16
      4 @rhs = global fp128 zeroinitializer, align 16
      5 
      6 define fp128 @test_add() {
      7 ; CHECK-LABEL: test_add:
      8 
      9   %lhs = load fp128, fp128* @lhs, align 16
     10   %rhs = load fp128, fp128* @rhs, align 16
     11 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
     12 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
     13 
     14   %val = fadd fp128 %lhs, %rhs
     15 ; CHECK: bl __addtf3
     16   ret fp128 %val
     17 }
     18 
     19 define fp128 @test_sub() {
     20 ; CHECK-LABEL: test_sub:
     21 
     22   %lhs = load fp128, fp128* @lhs, align 16
     23   %rhs = load fp128, fp128* @rhs, align 16
     24 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
     25 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
     26 
     27   %val = fsub fp128 %lhs, %rhs
     28 ; CHECK: bl __subtf3
     29   ret fp128 %val
     30 }
     31 
     32 define fp128 @test_mul() {
     33 ; CHECK-LABEL: test_mul:
     34 
     35   %lhs = load fp128, fp128* @lhs, align 16
     36   %rhs = load fp128, fp128* @rhs, align 16
     37 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
     38 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
     39 
     40   %val = fmul fp128 %lhs, %rhs
     41 ; CHECK: bl __multf3
     42   ret fp128 %val
     43 }
     44 
     45 define fp128 @test_div() {
     46 ; CHECK-LABEL: test_div:
     47 
     48   %lhs = load fp128, fp128* @lhs, align 16
     49   %rhs = load fp128, fp128* @rhs, align 16
     50 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
     51 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
     52 
     53   %val = fdiv fp128 %lhs, %rhs
     54 ; CHECK: bl __divtf3
     55   ret fp128 %val
     56 }
     57 
     58 @var32 = global i32 0
     59 @var64 = global i64 0
     60 
     61 define void @test_fptosi() {
     62 ; CHECK-LABEL: test_fptosi:
     63   %val = load fp128, fp128* @lhs, align 16
     64 
     65   %val32 = fptosi fp128 %val to i32
     66   store i32 %val32, i32* @var32
     67 ; CHECK: bl __fixtfsi
     68 
     69   %val64 = fptosi fp128 %val to i64
     70   store i64 %val64, i64* @var64
     71 ; CHECK: bl __fixtfdi
     72 
     73   ret void
     74 }
     75 
     76 define void @test_fptoui() {
     77 ; CHECK-LABEL: test_fptoui:
     78   %val = load fp128, fp128* @lhs, align 16
     79 
     80   %val32 = fptoui fp128 %val to i32
     81   store i32 %val32, i32* @var32
     82 ; CHECK: bl __fixunstfsi
     83 
     84   %val64 = fptoui fp128 %val to i64
     85   store i64 %val64, i64* @var64
     86 ; CHECK: bl __fixunstfdi
     87 
     88   ret void
     89 }
     90 
     91 define void @test_sitofp() {
     92 ; CHECK-LABEL: test_sitofp:
     93 
     94   %src32 = load i32, i32* @var32
     95   %val32 = sitofp i32 %src32 to fp128
     96   store volatile fp128 %val32, fp128* @lhs
     97 ; CHECK: bl __floatsitf
     98 
     99   %src64 = load i64, i64* @var64
    100   %val64 = sitofp i64 %src64 to fp128
    101   store volatile fp128 %val64, fp128* @lhs
    102 ; CHECK: bl __floatditf
    103 
    104   ret void
    105 }
    106 
    107 define void @test_uitofp() {
    108 ; CHECK-LABEL: test_uitofp:
    109 
    110   %src32 = load i32, i32* @var32
    111   %val32 = uitofp i32 %src32 to fp128
    112   store volatile fp128 %val32, fp128* @lhs
    113 ; CHECK: bl __floatunsitf
    114 
    115   %src64 = load i64, i64* @var64
    116   %val64 = uitofp i64 %src64 to fp128
    117   store volatile fp128 %val64, fp128* @lhs
    118 ; CHECK: bl __floatunditf
    119 
    120   ret void
    121 }
    122 
    123 define i1 @test_setcc1() {
    124 ; CHECK-LABEL: test_setcc1:
    125 
    126   %lhs = load fp128, fp128* @lhs, align 16
    127   %rhs = load fp128, fp128* @rhs, align 16
    128 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
    129 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
    130 
    131 ; Technically, everything after the call to __letf2 is redundant, but we'll let
    132 ; LLVM have its fun for now.
    133   %val = fcmp ole fp128 %lhs, %rhs
    134 ; CHECK: bl __letf2
    135 ; CHECK: cmp w0, #0
    136 ; CHECK: cset w0, le
    137 
    138   ret i1 %val
    139 ; CHECK: ret
    140 }
    141 
    142 define i1 @test_setcc2() {
    143 ; CHECK-LABEL: test_setcc2:
    144 
    145   %lhs = load fp128, fp128* @lhs, align 16
    146   %rhs = load fp128, fp128* @rhs, align 16
    147 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
    148 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
    149 
    150   %val = fcmp ugt fp128 %lhs, %rhs
    151 ; CHECK: bl      __letf2
    152 ; CHECK: cmp     w0, #0
    153 ; CHECK: cset    w0, gt
    154 
    155   ret i1 %val
    156 ; CHECK: ret
    157 }
    158 
    159 define i32 @test_br_cc() {
    160 ; CHECK-LABEL: test_br_cc:
    161 
    162   %lhs = load fp128, fp128* @lhs, align 16
    163   %rhs = load fp128, fp128* @rhs, align 16
    164 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:lhs]
    165 ; CHECK: ldr q1, [{{x[0-9]+}}, :lo12:rhs]
    166 
    167   ; olt == !uge, which LLVM optimizes this to.
    168   %cond = fcmp olt fp128 %lhs, %rhs
    169 ; CHECK: bl      __lttf2
    170 ; CHECK-NEXT: cmp     w0, #0
    171 ; CHECK-NEXT: b.ge {{.LBB[0-9]+_[0-9]+}}
    172   br i1 %cond, label %iftrue, label %iffalse
    173 
    174 iftrue:
    175   ret i32 42
    176 ; CHECK-NEXT: BB#
    177 ; CHECK-NEXT: movz w0, #0x2a
    178 ; CHECK: ret
    179 iffalse:
    180   ret i32 29
    181 ; CHECK: movz w0, #0x1d
    182 ; CHECK: ret
    183 }
    184 
    185 define void @test_select(i1 %cond, fp128 %lhs, fp128 %rhs) {
    186 ; CHECK-LABEL: test_select:
    187 
    188   %val = select i1 %cond, fp128 %lhs, fp128 %rhs
    189   store fp128 %val, fp128* @lhs, align 16
    190 ; CHECK: tst w0, #0x1
    191 ; CHECK-NEXT: b.eq [[IFFALSE:.LBB[0-9]+_[0-9]+]]
    192 ; CHECK-NEXT: BB#
    193 ; CHECK-NEXT: mov v[[VAL:[0-9]+]].16b, v0.16b
    194 ; CHECK-NEXT: [[IFFALSE]]:
    195 ; CHECK: str q[[VAL]], [{{x[0-9]+}}, :lo12:lhs]
    196   ret void
    197 ; CHECK: ret
    198 }
    199 
    200 @varfloat = global float 0.0, align 4
    201 @vardouble = global double 0.0, align 8
    202 
    203 define void @test_round() {
    204 ; CHECK-LABEL: test_round:
    205 
    206   %val = load fp128, fp128* @lhs, align 16
    207 
    208   %float = fptrunc fp128 %val to float
    209   store float %float, float* @varfloat, align 4
    210 ; CHECK: bl __trunctfsf2
    211 ; CHECK: str s0, [{{x[0-9]+}}, :lo12:varfloat]
    212 
    213   %double = fptrunc fp128 %val to double
    214   store double %double, double* @vardouble, align 8
    215 ; CHECK: bl __trunctfdf2
    216 ; CHECK: str d0, [{{x[0-9]+}}, :lo12:vardouble]
    217 
    218   ret void
    219 }
    220 
    221 define void @test_extend() {
    222 ; CHECK-LABEL: test_extend:
    223 
    224   %val = load fp128, fp128* @lhs, align 16
    225 
    226   %float = load float, float* @varfloat
    227   %fromfloat = fpext float %float to fp128
    228   store volatile fp128 %fromfloat, fp128* @lhs, align 16
    229 ; CHECK: bl __extendsftf2
    230 ; CHECK: str q0, [{{x[0-9]+}}, :lo12:lhs]
    231 
    232   %double = load double, double* @vardouble
    233   %fromdouble = fpext double %double to fp128
    234   store volatile fp128 %fromdouble, fp128* @lhs, align 16
    235 ; CHECK: bl __extenddftf2
    236 ; CHECK: str q0, [{{x[0-9]+}}, :lo12:lhs]
    237 
    238   ret void
    239 ; CHECK: ret
    240 }
    241 
    242 define fp128 @test_neg(fp128 %in) {
    243 ; CHECK: [[MINUS0:.LCPI[0-9]+_0]]:
    244 ; Make sure the weird hex constant below *is* -0.0
    245 ; CHECK-NEXT: fp128 -0
    246 
    247 ; CHECK-LABEL: test_neg:
    248 
    249   ; Could in principle be optimized to fneg which we can't select, this makes
    250   ; sure that doesn't happen.
    251   %ret = fsub fp128 0xL00000000000000008000000000000000, %in
    252 ; CHECK: mov v1.16b, v0.16b
    253 ; CHECK: ldr q0, [{{x[0-9]+}}, :lo12:[[MINUS0]]]
    254 ; CHECK: bl __subtf3
    255 
    256   ret fp128 %ret
    257 ; CHECK: ret
    258 }
    259