Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -mtriple=arm64-apple-ios -asm-verbose=false | FileCheck %s
      2 
      3 define float @load0(i16* nocapture readonly %a) nounwind {
      4 ; CHECK-LABEL: load0:
      5 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0]
      6 ; CHECK-NEXT: fcvt s0, [[HREG]]
      7 ; CHECK-NEXT: ret
      8 
      9   %tmp = load i16* %a, align 2
     10   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     11   ret float %tmp1
     12 }
     13 
     14 define double @load1(i16* nocapture readonly %a) nounwind {
     15 ; CHECK-LABEL: load1:
     16 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0]
     17 ; CHECK-NEXT: fcvt d0, [[HREG]]
     18 ; CHECK-NEXT: ret
     19 
     20   %tmp = load i16* %a, align 2
     21   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     22   %conv = fpext float %tmp1 to double
     23   ret double %conv
     24 }
     25 
     26 define float @load2(i16* nocapture readonly %a, i32 %i) nounwind {
     27 ; CHECK-LABEL: load2:
     28 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1]
     29 ; CHECK-NEXT: fcvt s0, [[HREG]]
     30 ; CHECK-NEXT: ret
     31 
     32   %idxprom = sext i32 %i to i64
     33   %arrayidx = getelementptr inbounds i16* %a, i64 %idxprom
     34   %tmp = load i16* %arrayidx, align 2
     35   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     36   ret float %tmp1
     37 }
     38 
     39 define double @load3(i16* nocapture readonly %a, i32 %i) nounwind {
     40 ; CHECK-LABEL: load3:
     41 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, w1, sxtw #1]
     42 ; CHECK-NEXT: fcvt d0, [[HREG]]
     43 ; CHECK-NEXT: ret
     44 
     45   %idxprom = sext i32 %i to i64
     46   %arrayidx = getelementptr inbounds i16* %a, i64 %idxprom
     47   %tmp = load i16* %arrayidx, align 2
     48   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     49   %conv = fpext float %tmp1 to double
     50   ret double %conv
     51 }
     52 
     53 define float @load4(i16* nocapture readonly %a, i64 %i) nounwind {
     54 ; CHECK-LABEL: load4:
     55 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1]
     56 ; CHECK-NEXT: fcvt s0, [[HREG]]
     57 ; CHECK-NEXT: ret
     58 
     59   %arrayidx = getelementptr inbounds i16* %a, i64 %i
     60   %tmp = load i16* %arrayidx, align 2
     61   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     62   ret float %tmp1
     63 }
     64 
     65 define double @load5(i16* nocapture readonly %a, i64 %i) nounwind {
     66 ; CHECK-LABEL: load5:
     67 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, x1, lsl #1]
     68 ; CHECK-NEXT: fcvt d0, [[HREG]]
     69 ; CHECK-NEXT: ret
     70 
     71   %arrayidx = getelementptr inbounds i16* %a, i64 %i
     72   %tmp = load i16* %arrayidx, align 2
     73   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     74   %conv = fpext float %tmp1 to double
     75   ret double %conv
     76 }
     77 
     78 define float @load6(i16* nocapture readonly %a) nounwind {
     79 ; CHECK-LABEL: load6:
     80 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20]
     81 ; CHECK-NEXT: fcvt s0, [[HREG]]
     82 ; CHECK-NEXT: ret
     83 
     84   %arrayidx = getelementptr inbounds i16* %a, i64 10
     85   %tmp = load i16* %arrayidx, align 2
     86   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     87   ret float %tmp1
     88 }
     89 
     90 define double @load7(i16* nocapture readonly %a) nounwind {
     91 ; CHECK-LABEL: load7:
     92 ; CHECK-NEXT: ldr [[HREG:h[0-9]+]], [x0, #20]
     93 ; CHECK-NEXT: fcvt d0, [[HREG]]
     94 ; CHECK-NEXT: ret
     95 
     96   %arrayidx = getelementptr inbounds i16* %a, i64 10
     97   %tmp = load i16* %arrayidx, align 2
     98   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
     99   %conv = fpext float %tmp1 to double
    100   ret double %conv
    101 }
    102 
    103 define float @load8(i16* nocapture readonly %a) nounwind {
    104 ; CHECK-LABEL: load8:
    105 ; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20]
    106 ; CHECK-NEXT: fcvt s0, [[HREG]]
    107 ; CHECK-NEXT: ret
    108 
    109   %arrayidx = getelementptr inbounds i16* %a, i64 -10
    110   %tmp = load i16* %arrayidx, align 2
    111   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
    112   ret float %tmp1
    113 }
    114 
    115 define double @load9(i16* nocapture readonly %a) nounwind {
    116 ; CHECK-LABEL: load9:
    117 ; CHECK-NEXT: ldur [[HREG:h[0-9]+]], [x0, #-20]
    118 ; CHECK-NEXT: fcvt d0, [[HREG]]
    119 ; CHECK-NEXT: ret
    120 
    121   %arrayidx = getelementptr inbounds i16* %a, i64 -10
    122   %tmp = load i16* %arrayidx, align 2
    123   %tmp1 = tail call float @llvm.convert.from.fp16(i16 %tmp)
    124   %conv = fpext float %tmp1 to double
    125   ret double %conv
    126 }
    127 
    128 define void @store0(i16* nocapture %a, float %val) nounwind {
    129 ; CHECK-LABEL: store0:
    130 ; CHECK-NEXT: fcvt h0, s0
    131 ; CHECK-NEXT: str  h0, [x0]
    132 ; CHECK-NEXT: ret
    133 
    134   %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
    135   store i16 %tmp, i16* %a, align 2
    136   ret void
    137 }
    138 
    139 define void @store1(i16* nocapture %a, double %val) nounwind {
    140 ; CHECK-LABEL: store1:
    141 ; CHECK-NEXT: fcvt h0, d0
    142 ; CHECK-NEXT: str  h0, [x0]
    143 ; CHECK-NEXT: ret
    144 
    145   %conv = fptrunc double %val to float
    146   %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
    147   store i16 %tmp, i16* %a, align 2
    148   ret void
    149 }
    150 
    151 define void @store2(i16* nocapture %a, i32 %i, float %val) nounwind {
    152 ; CHECK-LABEL: store2:
    153 ; CHECK-NEXT: fcvt h0, s0
    154 ; CHECK-NEXT: str h0, [x0, w1, sxtw #1]
    155 ; CHECK-NEXT: ret
    156 
    157   %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
    158   %idxprom = sext i32 %i to i64
    159   %arrayidx = getelementptr inbounds i16* %a, i64 %idxprom
    160   store i16 %tmp, i16* %arrayidx, align 2
    161   ret void
    162 }
    163 
    164 define void @store3(i16* nocapture %a, i32 %i, double %val) nounwind {
    165 ; CHECK-LABEL: store3:
    166 ; CHECK-NEXT: fcvt h0, d0
    167 ; CHECK-NEXT: str h0, [x0, w1, sxtw #1]
    168 ; CHECK-NEXT: ret
    169 
    170   %conv = fptrunc double %val to float
    171   %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
    172   %idxprom = sext i32 %i to i64
    173   %arrayidx = getelementptr inbounds i16* %a, i64 %idxprom
    174   store i16 %tmp, i16* %arrayidx, align 2
    175   ret void
    176 }
    177 
    178 define void @store4(i16* nocapture %a, i64 %i, float %val) nounwind {
    179 ; CHECK-LABEL: store4:
    180 ; CHECK-NEXT: fcvt h0, s0
    181 ; CHECK-NEXT: str h0, [x0, x1, lsl #1]
    182 ; CHECK-NEXT: ret
    183 
    184   %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
    185   %arrayidx = getelementptr inbounds i16* %a, i64 %i
    186   store i16 %tmp, i16* %arrayidx, align 2
    187   ret void
    188 }
    189 
    190 define void @store5(i16* nocapture %a, i64 %i, double %val) nounwind {
    191 ; CHECK-LABEL: store5:
    192 ; CHECK-NEXT: fcvt h0, d0
    193 ; CHECK-NEXT: str h0, [x0, x1, lsl #1]
    194 ; CHECK-NEXT: ret
    195 
    196   %conv = fptrunc double %val to float
    197   %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
    198   %arrayidx = getelementptr inbounds i16* %a, i64 %i
    199   store i16 %tmp, i16* %arrayidx, align 2
    200   ret void
    201 }
    202 
    203 define void @store6(i16* nocapture %a, float %val) nounwind {
    204 ; CHECK-LABEL: store6:
    205 ; CHECK-NEXT: fcvt h0, s0
    206 ; CHECK-NEXT: str h0, [x0, #20]
    207 ; CHECK-NEXT: ret
    208 
    209   %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
    210   %arrayidx = getelementptr inbounds i16* %a, i64 10
    211   store i16 %tmp, i16* %arrayidx, align 2
    212   ret void
    213 }
    214 
    215 define void @store7(i16* nocapture %a, double %val) nounwind {
    216 ; CHECK-LABEL: store7:
    217 ; CHECK-NEXT: fcvt h0, d0
    218 ; CHECK-NEXT: str h0, [x0, #20]
    219 ; CHECK-NEXT: ret
    220 
    221   %conv = fptrunc double %val to float
    222   %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
    223   %arrayidx = getelementptr inbounds i16* %a, i64 10
    224   store i16 %tmp, i16* %arrayidx, align 2
    225   ret void
    226 }
    227 
    228 define void @store8(i16* nocapture %a, float %val) nounwind {
    229 ; CHECK-LABEL: store8:
    230 ; CHECK-NEXT: fcvt h0, s0
    231 ; CHECK-NEXT: stur h0, [x0, #-20]
    232 ; CHECK-NEXT: ret
    233 
    234   %tmp = tail call i16 @llvm.convert.to.fp16(float %val)
    235   %arrayidx = getelementptr inbounds i16* %a, i64 -10
    236   store i16 %tmp, i16* %arrayidx, align 2
    237   ret void
    238 }
    239 
    240 define void @store9(i16* nocapture %a, double %val) nounwind {
    241 ; CHECK-LABEL: store9:
    242 ; CHECK-NEXT: fcvt h0, d0
    243 ; CHECK-NEXT: stur h0, [x0, #-20]
    244 ; CHECK-NEXT: ret
    245 
    246   %conv = fptrunc double %val to float
    247   %tmp = tail call i16 @llvm.convert.to.fp16(float %conv)
    248   %arrayidx = getelementptr inbounds i16* %a, i64 -10
    249   store i16 %tmp, i16* %arrayidx, align 2
    250   ret void
    251 }
    252 
    253 declare i16 @llvm.convert.to.fp16(float) nounwind readnone
    254 declare float @llvm.convert.from.fp16(i16) nounwind readnone
    255