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