Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
      2 
      3 @var32 = global i32 0
      4 @var64 = global i64 0
      5 
      6 define void @test_extendb32(i8 %var) {
      7 ; CHECK-LABEL: test_extendb32:
      8 
      9   %sxt32 = sext i8 %var to i32
     10   store volatile i32 %sxt32, i32* @var32
     11 ; CHECK: sxtb {{w[0-9]+}}, {{w[0-9]+}}
     12 
     13 ; N.b. this doesn't actually produce a bitfield instruction at the
     14 ; moment, but it's still a good test to have and the semantics are
     15 ; correct.
     16   %uxt32 = zext i8 %var to i32
     17   store volatile i32 %uxt32, i32* @var32
     18 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xff
     19   ret void
     20 }
     21 
     22 define void @test_extendb64(i8 %var) {
     23 ; CHECK-LABEL: test_extendb64:
     24 
     25   %sxt64 = sext i8 %var to i64
     26   store volatile i64 %sxt64, i64* @var64
     27 ; CHECK: sxtb {{x[0-9]+}}, {{w[0-9]+}}
     28 
     29 ; N.b. this doesn't actually produce a bitfield instruction at the
     30 ; moment, but it's still a good test to have and the semantics are
     31 ; correct.
     32   %uxt64 = zext i8 %var to i64
     33   store volatile i64 %uxt64, i64* @var64
     34 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xff
     35   ret void
     36 }
     37 
     38 define void @test_extendh32(i16 %var) {
     39 ; CHECK-LABEL: test_extendh32:
     40 
     41   %sxt32 = sext i16 %var to i32
     42   store volatile i32 %sxt32, i32* @var32
     43 ; CHECK: sxth {{w[0-9]+}}, {{w[0-9]+}}
     44 
     45 ; N.b. this doesn't actually produce a bitfield instruction at the
     46 ; moment, but it's still a good test to have and the semantics are
     47 ; correct.
     48   %uxt32 = zext i16 %var to i32
     49   store volatile i32 %uxt32, i32* @var32
     50 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xffff
     51   ret void
     52 }
     53 
     54 define void @test_extendh64(i16 %var) {
     55 ; CHECK-LABEL: test_extendh64:
     56 
     57   %sxt64 = sext i16 %var to i64
     58   store volatile i64 %sxt64, i64* @var64
     59 ; CHECK: sxth {{x[0-9]+}}, {{w[0-9]+}}
     60 
     61 ; N.b. this doesn't actually produce a bitfield instruction at the
     62 ; moment, but it's still a good test to have and the semantics are
     63 ; correct.
     64   %uxt64 = zext i16 %var to i64
     65   store volatile i64 %uxt64, i64* @var64
     66 ; CHECK: and {{w[0-9]+}}, {{w[0-9]+}}, #0xffff
     67   ret void
     68 }
     69 
     70 define void @test_extendw(i32 %var) {
     71 ; CHECK-LABEL: test_extendw:
     72 
     73   %sxt64 = sext i32 %var to i64
     74   store volatile i64 %sxt64, i64* @var64
     75 ; CHECK: sxtw {{x[0-9]+}}, {{w[0-9]+}}
     76 
     77   %uxt64 = zext i32 %var to i64
     78   store volatile i64 %uxt64, i64* @var64
     79 ; CHECK: mov {{w[0-9]+}}, w0
     80   ret void
     81 }
     82 
     83 define void @test_shifts(i32 %val32, i64 %val64) {
     84 ; CHECK-LABEL: test_shifts:
     85 
     86   %shift1 = ashr i32 %val32, 31
     87   store volatile i32 %shift1, i32* @var32
     88 ; CHECK: asr {{w[0-9]+}}, {{w[0-9]+}}, #31
     89 
     90   %shift2 = lshr i32 %val32, 8
     91   store volatile i32 %shift2, i32* @var32
     92 ; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, #8
     93 
     94   %shift3 = shl i32 %val32, 1
     95   store volatile i32 %shift3, i32* @var32
     96 ; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, #1
     97 
     98   %shift4 = ashr i64 %val64, 31
     99   store volatile i64 %shift4, i64* @var64
    100 ; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, #31
    101 
    102   %shift5 = lshr i64 %val64, 8
    103   store volatile i64 %shift5, i64* @var64
    104 ; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, #8
    105 
    106   %shift6 = shl i64 %val64, 63
    107   store volatile i64 %shift6, i64* @var64
    108 ; CHECK: lsl {{x[0-9]+}}, {{x[0-9]+}}, #63
    109 
    110   %shift7 = ashr i64 %val64, 63
    111   store volatile i64 %shift7, i64* @var64
    112 ; CHECK: asr {{x[0-9]+}}, {{x[0-9]+}}, #63
    113 
    114   %shift8 = lshr i64 %val64, 63
    115   store volatile i64 %shift8, i64* @var64
    116 ; CHECK: lsr {{x[0-9]+}}, {{x[0-9]+}}, #63
    117 
    118   %shift9 = lshr i32 %val32, 31
    119   store volatile i32 %shift9, i32* @var32
    120 ; CHECK: lsr {{w[0-9]+}}, {{w[0-9]+}}, #31
    121 
    122   %shift10 = shl i32 %val32, 31
    123   store volatile i32 %shift10, i32* @var32
    124 ; CHECK: lsl {{w[0-9]+}}, {{w[0-9]+}}, #31
    125 
    126   ret void
    127 }
    128 
    129 ; LLVM can produce in-register extensions taking place entirely with
    130 ; 64-bit registers too.
    131 define void @test_sext_inreg_64(i64 %in) {
    132 ; CHECK-LABEL: test_sext_inreg_64:
    133 
    134 ; i1 doesn't have an official alias, but crops up and is handled by
    135 ; the bitfield ops.
    136   %trunc_i1 = trunc i64 %in to i1
    137   %sext_i1 = sext i1 %trunc_i1 to i64
    138   store volatile i64 %sext_i1, i64* @var64
    139 ; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #1
    140 
    141   %trunc_i8 = trunc i64 %in to i8
    142   %sext_i8 = sext i8 %trunc_i8 to i64
    143   store volatile i64 %sext_i8, i64* @var64
    144 ; CHECK: sxtb {{x[0-9]+}}, {{w[0-9]+}}
    145 
    146   %trunc_i16 = trunc i64 %in to i16
    147   %sext_i16 = sext i16 %trunc_i16 to i64
    148   store volatile i64 %sext_i16, i64* @var64
    149 ; CHECK: sxth {{x[0-9]+}}, {{w[0-9]+}}
    150 
    151   %trunc_i32 = trunc i64 %in to i32
    152   %sext_i32 = sext i32 %trunc_i32 to i64
    153   store volatile i64 %sext_i32, i64* @var64
    154 ; CHECK: sxtw {{x[0-9]+}}, {{w[0-9]+}}
    155   ret void
    156 }
    157 
    158 ; These instructions don't actually select to official bitfield
    159 ; operations, but it's important that we select them somehow:
    160 define void @test_zext_inreg_64(i64 %in) {
    161 ; CHECK-LABEL: test_zext_inreg_64:
    162 
    163   %trunc_i8 = trunc i64 %in to i8
    164   %zext_i8 = zext i8 %trunc_i8 to i64
    165   store volatile i64 %zext_i8, i64* @var64
    166 ; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xff
    167 
    168   %trunc_i16 = trunc i64 %in to i16
    169   %zext_i16 = zext i16 %trunc_i16 to i64
    170   store volatile i64 %zext_i16, i64* @var64
    171 ; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffff
    172 
    173   %trunc_i32 = trunc i64 %in to i32
    174   %zext_i32 = zext i32 %trunc_i32 to i64
    175   store volatile i64 %zext_i32, i64* @var64
    176 ; CHECK: and {{x[0-9]+}}, {{x[0-9]+}}, #0xffffffff
    177 
    178   ret void
    179 }
    180 
    181 define i64 @test_sext_inreg_from_32(i32 %in) {
    182 ; CHECK-LABEL: test_sext_inreg_from_32:
    183 
    184   %small = trunc i32 %in to i1
    185   %ext = sext i1 %small to i64
    186 
    187   ; Different registers are of course, possible, though suboptimal. This is
    188   ; making sure that a 64-bit "(sext_inreg (anyext GPR32), i1)" uses the 64-bit
    189   ; sbfx rather than just 32-bits.
    190 ; CHECK: sbfx x0, x0, #0, #1
    191   ret i64 %ext
    192 }
    193 
    194 
    195 define i32 @test_ubfx32(i32* %addr) {
    196 ; CHECK-LABEL: test_ubfx32:
    197 ; CHECK: ubfx {{w[0-9]+}}, {{w[0-9]+}}, #23, #3
    198 
    199    %fields = load i32, i32* %addr
    200    %shifted = lshr i32 %fields, 23
    201    %masked = and i32 %shifted, 7
    202    ret i32 %masked
    203 }
    204 
    205 define i64 @test_ubfx64(i64* %addr) {
    206 ; CHECK-LABEL: test_ubfx64:
    207 ; CHECK: ubfx {{x[0-9]+}}, {{x[0-9]+}}, #25, #10
    208    %fields = load i64, i64* %addr
    209    %shifted = lshr i64 %fields, 25
    210    %masked = and i64 %shifted, 1023
    211    ret i64 %masked
    212 }
    213 
    214 define i32 @test_sbfx32(i32* %addr) {
    215 ; CHECK-LABEL: test_sbfx32:
    216 ; CHECK: sbfx {{w[0-9]+}}, {{w[0-9]+}}, #6, #3
    217 
    218    %fields = load i32, i32* %addr
    219    %shifted = shl i32 %fields, 23
    220    %extended = ashr i32 %shifted, 29
    221    ret i32 %extended
    222 }
    223 
    224 define i64 @test_sbfx64(i64* %addr) {
    225 ; CHECK-LABEL: test_sbfx64:
    226 ; CHECK: sbfx {{x[0-9]+}}, {{x[0-9]+}}, #0, #63
    227 
    228    %fields = load i64, i64* %addr
    229    %shifted = shl i64 %fields, 1
    230    %extended = ashr i64 %shifted, 1
    231    ret i64 %extended
    232 }
    233