Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
      2 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
      3 
      4 @var_8bit = global i8 0
      5 @var_16bit = global i16 0
      6 @var_32bit = global i32 0
      7 @var_64bit = global i64 0
      8 
      9 @var_float = global float 0.0
     10 @var_double = global double 0.0
     11 
     12 define void @ldst_8bit(i8* %base, i32 %off32, i64 %off64) minsize {
     13 ; CHECK-LABEL: ldst_8bit:
     14 
     15    %addr8_sxtw = getelementptr i8, i8* %base, i32 %off32
     16    %val8_sxtw = load volatile i8, i8* %addr8_sxtw
     17    %val32_signed = sext i8 %val8_sxtw to i32
     18    store volatile i32 %val32_signed, i32* @var_32bit
     19 ; CHECK: ldrsb {{w[0-9]+}}, [{{x[0-9]+}}, {{[wx][0-9]+}}, sxtw]
     20 
     21   %addr_lsl = getelementptr i8, i8* %base, i64 %off64
     22   %val8_lsl = load volatile i8, i8* %addr_lsl
     23   %val32_unsigned = zext i8 %val8_lsl to i32
     24   store volatile i32 %val32_unsigned, i32* @var_32bit
     25 ; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
     26 
     27   %addrint_uxtw = ptrtoint i8* %base to i64
     28   %offset_uxtw = zext i32 %off32 to i64
     29   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
     30   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i8*
     31   %val8_uxtw = load volatile i8, i8* %addr_uxtw
     32   %newval8 = add i8 %val8_uxtw, 1
     33   store volatile i8 %newval8, i8* @var_8bit
     34 ; CHECK: ldrb {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
     35 
     36    ret void
     37 }
     38 
     39 
     40 define void @ldst_16bit(i16* %base, i32 %off32, i64 %off64) minsize {
     41 ; CHECK-LABEL: ldst_16bit:
     42 
     43    %addr8_sxtwN = getelementptr i16, i16* %base, i32 %off32
     44    %val8_sxtwN = load volatile i16, i16* %addr8_sxtwN
     45    %val32_signed = sext i16 %val8_sxtwN to i32
     46    store volatile i32 %val32_signed, i32* @var_32bit
     47 ; CHECK: ldrsh {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #1]
     48 
     49   %addr_lslN = getelementptr i16, i16* %base, i64 %off64
     50   %val8_lslN = load volatile i16, i16* %addr_lslN
     51   %val32_unsigned = zext i16 %val8_lslN to i32
     52   store volatile i32 %val32_unsigned, i32* @var_32bit
     53 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #1]
     54 
     55   %addrint_uxtw = ptrtoint i16* %base to i64
     56   %offset_uxtw = zext i32 %off32 to i64
     57   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
     58   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i16*
     59   %val8_uxtw = load volatile i16, i16* %addr_uxtw
     60   %newval8 = add i16 %val8_uxtw, 1
     61   store volatile i16 %newval8, i16* @var_16bit
     62 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
     63 
     64   %base_sxtw = ptrtoint i16* %base to i64
     65   %offset_sxtw = sext i32 %off32 to i64
     66   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
     67   %addr_sxtw = inttoptr i64 %addrint_sxtw to i16*
     68   %val16_sxtw = load volatile i16, i16* %addr_sxtw
     69   %val64_signed = sext i16 %val16_sxtw to i64
     70   store volatile i64 %val64_signed, i64* @var_64bit
     71 ; CHECK: ldrsh {{x[0-9]+}}, [{{x[0-9]+}}, {{[wx][0-9]+}}, sxtw]
     72 
     73 
     74   %base_lsl = ptrtoint i16* %base to i64
     75   %addrint_lsl = add i64 %base_lsl, %off64
     76   %addr_lsl = inttoptr i64 %addrint_lsl to i16*
     77   %val16_lsl = load volatile i16, i16* %addr_lsl
     78   %val64_unsigned = zext i16 %val16_lsl to i64
     79   store volatile i64 %val64_unsigned, i64* @var_64bit
     80 ; CHECK: ldrh {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
     81 
     82   %base_uxtwN = ptrtoint i16* %base to i64
     83   %offset_uxtwN = zext i32 %off32 to i64
     84   %offset2_uxtwN = shl i64 %offset_uxtwN, 1
     85   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
     86   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i16*
     87   %val32 = load volatile i32, i32* @var_32bit
     88   %val16_trunc32 = trunc i32 %val32 to i16
     89   store volatile i16 %val16_trunc32, i16* %addr_uxtwN
     90 ; CHECK: strh {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #1]
     91    ret void
     92 }
     93 
     94 define void @ldst_32bit(i32* %base, i32 %off32, i64 %off64) minsize {
     95 ; CHECK-LABEL: ldst_32bit:
     96 
     97    %addr_sxtwN = getelementptr i32, i32* %base, i32 %off32
     98    %val_sxtwN = load volatile i32, i32* %addr_sxtwN
     99    store volatile i32 %val_sxtwN, i32* @var_32bit
    100 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #2]
    101 
    102   %addr_lslN = getelementptr i32, i32* %base, i64 %off64
    103   %val_lslN = load volatile i32, i32* %addr_lslN
    104   store volatile i32 %val_lslN, i32* @var_32bit
    105 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2]
    106 
    107   %addrint_uxtw = ptrtoint i32* %base to i64
    108   %offset_uxtw = zext i32 %off32 to i64
    109   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
    110   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i32*
    111   %val_uxtw = load volatile i32, i32* %addr_uxtw
    112   %newval8 = add i32 %val_uxtw, 1
    113   store volatile i32 %newval8, i32* @var_32bit
    114 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
    115 
    116 
    117   %base_sxtw = ptrtoint i32* %base to i64
    118   %offset_sxtw = sext i32 %off32 to i64
    119   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
    120   %addr_sxtw = inttoptr i64 %addrint_sxtw to i32*
    121   %val16_sxtw = load volatile i32, i32* %addr_sxtw
    122   %val64_signed = sext i32 %val16_sxtw to i64
    123   store volatile i64 %val64_signed, i64* @var_64bit
    124 ; CHECK: ldrsw {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw]
    125 
    126 
    127   %base_lsl = ptrtoint i32* %base to i64
    128   %addrint_lsl = add i64 %base_lsl, %off64
    129   %addr_lsl = inttoptr i64 %addrint_lsl to i32*
    130   %val16_lsl = load volatile i32, i32* %addr_lsl
    131   %val64_unsigned = zext i32 %val16_lsl to i64
    132   store volatile i64 %val64_unsigned, i64* @var_64bit
    133 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
    134 
    135   %base_uxtwN = ptrtoint i32* %base to i64
    136   %offset_uxtwN = zext i32 %off32 to i64
    137   %offset2_uxtwN = shl i64 %offset_uxtwN, 2
    138   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
    139   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i32*
    140   %val32 = load volatile i32, i32* @var_32bit
    141   store volatile i32 %val32, i32* %addr_uxtwN
    142 ; CHECK: str {{w[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #2]
    143    ret void
    144 }
    145 
    146 define void @ldst_64bit(i64* %base, i32 %off32, i64 %off64) minsize {
    147 ; CHECK-LABEL: ldst_64bit:
    148 
    149    %addr_sxtwN = getelementptr i64, i64* %base, i32 %off32
    150    %val_sxtwN = load volatile i64, i64* %addr_sxtwN
    151    store volatile i64 %val_sxtwN, i64* @var_64bit
    152 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #3]
    153 
    154   %addr_lslN = getelementptr i64, i64* %base, i64 %off64
    155   %val_lslN = load volatile i64, i64* %addr_lslN
    156   store volatile i64 %val_lslN, i64* @var_64bit
    157 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3]
    158 
    159   %addrint_uxtw = ptrtoint i64* %base to i64
    160   %offset_uxtw = zext i32 %off32 to i64
    161   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
    162   %addr_uxtw = inttoptr i64 %addrint1_uxtw to i64*
    163   %val8_uxtw = load volatile i64, i64* %addr_uxtw
    164   %newval8 = add i64 %val8_uxtw, 1
    165   store volatile i64 %newval8, i64* @var_64bit
    166 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
    167 
    168   %base_sxtw = ptrtoint i64* %base to i64
    169   %offset_sxtw = sext i32 %off32 to i64
    170   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
    171   %addr_sxtw = inttoptr i64 %addrint_sxtw to i64*
    172   %val64_sxtw = load volatile i64, i64* %addr_sxtw
    173   store volatile i64 %val64_sxtw, i64* @var_64bit
    174 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw]
    175 
    176   %base_lsl = ptrtoint i64* %base to i64
    177   %addrint_lsl = add i64 %base_lsl, %off64
    178   %addr_lsl = inttoptr i64 %addrint_lsl to i64*
    179   %val64_lsl = load volatile i64, i64* %addr_lsl
    180   store volatile i64 %val64_lsl, i64* @var_64bit
    181 ; CHECK: ldr {{x[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
    182 
    183   %base_uxtwN = ptrtoint i64* %base to i64
    184   %offset_uxtwN = zext i32 %off32 to i64
    185   %offset2_uxtwN = shl i64 %offset_uxtwN, 3
    186   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
    187   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to i64*
    188   %val64 = load volatile i64, i64* @var_64bit
    189   store volatile i64 %val64, i64* %addr_uxtwN
    190 ; CHECK: str {{x[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #3]
    191    ret void
    192 }
    193 
    194 define void @ldst_float(float* %base, i32 %off32, i64 %off64) minsize {
    195 ; CHECK-LABEL: ldst_float:
    196 
    197    %addr_sxtwN = getelementptr float, float* %base, i32 %off32
    198    %val_sxtwN = load volatile float, float* %addr_sxtwN
    199    store volatile float %val_sxtwN, float* @var_float
    200 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #2]
    201 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
    202 
    203   %addr_lslN = getelementptr float, float* %base, i64 %off64
    204   %val_lslN = load volatile float, float* %addr_lslN
    205   store volatile float %val_lslN, float* @var_float
    206 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #2]
    207 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
    208 
    209   %addrint_uxtw = ptrtoint float* %base to i64
    210   %offset_uxtw = zext i32 %off32 to i64
    211   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
    212   %addr_uxtw = inttoptr i64 %addrint1_uxtw to float*
    213   %val_uxtw = load volatile float, float* %addr_uxtw
    214   store volatile float %val_uxtw, float* @var_float
    215 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
    216 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
    217 
    218   %base_sxtw = ptrtoint float* %base to i64
    219   %offset_sxtw = sext i32 %off32 to i64
    220   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
    221   %addr_sxtw = inttoptr i64 %addrint_sxtw to float*
    222   %val64_sxtw = load volatile float, float* %addr_sxtw
    223   store volatile float %val64_sxtw, float* @var_float
    224 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw]
    225 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
    226 
    227   %base_lsl = ptrtoint float* %base to i64
    228   %addrint_lsl = add i64 %base_lsl, %off64
    229   %addr_lsl = inttoptr i64 %addrint_lsl to float*
    230   %val64_lsl = load volatile float, float* %addr_lsl
    231   store volatile float %val64_lsl, float* @var_float
    232 ; CHECK: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
    233 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
    234 
    235   %base_uxtwN = ptrtoint float* %base to i64
    236   %offset_uxtwN = zext i32 %off32 to i64
    237   %offset2_uxtwN = shl i64 %offset_uxtwN, 2
    238   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
    239   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to float*
    240   %val64 = load volatile float, float* @var_float
    241   store volatile float %val64, float* %addr_uxtwN
    242 ; CHECK: str {{s[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #2]
    243 ; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
    244    ret void
    245 }
    246 
    247 define void @ldst_double(double* %base, i32 %off32, i64 %off64) minsize {
    248 ; CHECK-LABEL: ldst_double:
    249 
    250    %addr_sxtwN = getelementptr double, double* %base, i32 %off32
    251    %val_sxtwN = load volatile double, double* %addr_sxtwN
    252    store volatile double %val_sxtwN, double* @var_double
    253 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #3]
    254 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
    255 
    256   %addr_lslN = getelementptr double, double* %base, i64 %off64
    257   %val_lslN = load volatile double, double* %addr_lslN
    258   store volatile double %val_lslN, double* @var_double
    259 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #3]
    260 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
    261 
    262   %addrint_uxtw = ptrtoint double* %base to i64
    263   %offset_uxtw = zext i32 %off32 to i64
    264   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
    265   %addr_uxtw = inttoptr i64 %addrint1_uxtw to double*
    266   %val_uxtw = load volatile double, double* %addr_uxtw
    267   store volatile double %val_uxtw, double* @var_double
    268 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
    269 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
    270 
    271   %base_sxtw = ptrtoint double* %base to i64
    272   %offset_sxtw = sext i32 %off32 to i64
    273   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
    274   %addr_sxtw = inttoptr i64 %addrint_sxtw to double*
    275   %val64_sxtw = load volatile double, double* %addr_sxtw
    276   store volatile double %val64_sxtw, double* @var_double
    277 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw]
    278 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
    279 
    280   %base_lsl = ptrtoint double* %base to i64
    281   %addrint_lsl = add i64 %base_lsl, %off64
    282   %addr_lsl = inttoptr i64 %addrint_lsl to double*
    283   %val64_lsl = load volatile double, double* %addr_lsl
    284   store volatile double %val64_lsl, double* @var_double
    285 ; CHECK: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
    286 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
    287 
    288   %base_uxtwN = ptrtoint double* %base to i64
    289   %offset_uxtwN = zext i32 %off32 to i64
    290   %offset2_uxtwN = shl i64 %offset_uxtwN, 3
    291   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
    292   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to double*
    293   %val64 = load volatile double, double* @var_double
    294   store volatile double %val64, double* %addr_uxtwN
    295 ; CHECK: str {{d[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #3]
    296 ; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
    297    ret void
    298 }
    299 
    300 
    301 define void @ldst_128bit(fp128* %base, i32 %off32, i64 %off64) minsize {
    302 ; CHECK-LABEL: ldst_128bit:
    303 
    304    %addr_sxtwN = getelementptr fp128, fp128* %base, i32 %off32
    305    %val_sxtwN = load volatile fp128, fp128* %addr_sxtwN
    306    store volatile fp128 %val_sxtwN, fp128* %base
    307 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    308 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    309 
    310   %addr_lslN = getelementptr fp128, fp128* %base, i64 %off64
    311   %val_lslN = load volatile fp128, fp128* %addr_lslN
    312   store volatile fp128 %val_lslN, fp128* %base
    313 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}, lsl #4]
    314 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    315 
    316   %addrint_uxtw = ptrtoint fp128* %base to i64
    317   %offset_uxtw = zext i32 %off32 to i64
    318   %addrint1_uxtw = add i64 %addrint_uxtw, %offset_uxtw
    319   %addr_uxtw = inttoptr i64 %addrint1_uxtw to fp128*
    320   %val_uxtw = load volatile fp128, fp128* %addr_uxtw
    321   store volatile fp128 %val_uxtw, fp128* %base
    322 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw]
    323 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    324 
    325   %base_sxtw = ptrtoint fp128* %base to i64
    326   %offset_sxtw = sext i32 %off32 to i64
    327   %addrint_sxtw = add i64 %base_sxtw, %offset_sxtw
    328   %addr_sxtw = inttoptr i64 %addrint_sxtw to fp128*
    329   %val64_sxtw = load volatile fp128, fp128* %addr_sxtw
    330   store volatile fp128 %val64_sxtw, fp128* %base
    331 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw]
    332 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    333 
    334   %base_lsl = ptrtoint fp128* %base to i64
    335   %addrint_lsl = add i64 %base_lsl, %off64
    336   %addr_lsl = inttoptr i64 %addrint_lsl to fp128*
    337   %val64_lsl = load volatile fp128, fp128* %addr_lsl
    338   store volatile fp128 %val64_lsl, fp128* %base
    339 ; CHECK: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{x[0-9]+}}]
    340 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    341 
    342   %base_uxtwN = ptrtoint fp128* %base to i64
    343   %offset_uxtwN = zext i32 %off32 to i64
    344   %offset2_uxtwN = shl i64 %offset_uxtwN, 4
    345   %addrint_uxtwN = add i64 %base_uxtwN, %offset2_uxtwN
    346   %addr_uxtwN = inttoptr i64 %addrint_uxtwN to fp128*
    347   %val64 = load volatile fp128, fp128* %base
    348   store volatile fp128 %val64, fp128* %addr_uxtwN
    349 ; CHECK: str {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, uxtw #4]
    350 ; CHECK-NOFP-NOT: ldr {{q[0-9]+}}, [{{x[0-9]+}}, {{[xw][0-9]+}}, sxtw #4]
    351    ret void
    352 }
    353