Home | History | Annotate | Download | only in AArch64
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
      3 
      4 ; https://bugs.llvm.org/show_bug.cgi?id=37104
      5 
      6 ; X:               [byte1][byte0]
      7 ; Y: [byte3][byte2]
      8 
      9 define i8 @out8_constmask(i8 %x, i8 %y) {
     10 ; CHECK-LABEL: out8_constmask:
     11 ; CHECK:       // %bb.0:
     12 ; CHECK-NEXT:    bfxil w1, w0, #0, #4
     13 ; CHECK-NEXT:    mov w0, w1
     14 ; CHECK-NEXT:    ret
     15   %mx = and i8 %x, 15
     16   %my = and i8 %y, -16
     17   %r = or i8 %mx, %my
     18   ret i8 %r
     19 }
     20 
     21 define i16 @out16_constmask(i16 %x, i16 %y) {
     22 ; CHECK-LABEL: out16_constmask:
     23 ; CHECK:       // %bb.0:
     24 ; CHECK-NEXT:    bfxil w1, w0, #0, #8
     25 ; CHECK-NEXT:    mov w0, w1
     26 ; CHECK-NEXT:    ret
     27   %mx = and i16 %x, 255
     28   %my = and i16 %y, -256
     29   %r = or i16 %mx, %my
     30   ret i16 %r
     31 }
     32 
     33 define i32 @out32_constmask(i32 %x, i32 %y) {
     34 ; CHECK-LABEL: out32_constmask:
     35 ; CHECK:       // %bb.0:
     36 ; CHECK-NEXT:    bfxil w1, w0, #0, #16
     37 ; CHECK-NEXT:    mov w0, w1
     38 ; CHECK-NEXT:    ret
     39   %mx = and i32 %x, 65535
     40   %my = and i32 %y, -65536
     41   %r = or i32 %mx, %my
     42   ret i32 %r
     43 }
     44 
     45 define i64 @out64_constmask(i64 %x, i64 %y) {
     46 ; CHECK-LABEL: out64_constmask:
     47 ; CHECK:       // %bb.0:
     48 ; CHECK-NEXT:    bfxil x1, x0, #0, #32
     49 ; CHECK-NEXT:    mov x0, x1
     50 ; CHECK-NEXT:    ret
     51   %mx = and i64 %x, 4294967295
     52   %my = and i64 %y, -4294967296
     53   %r = or i64 %mx, %my
     54   ret i64 %r
     55 }
     56 
     57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     58 ; Should be the same as the previous one.
     59 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     60 
     61 define i8 @in8_constmask(i8 %x, i8 %y) {
     62 ; CHECK-LABEL: in8_constmask:
     63 ; CHECK:       // %bb.0:
     64 ; CHECK-NEXT:    eor w8, w0, w1
     65 ; CHECK-NEXT:    and w8, w8, #0xf
     66 ; CHECK-NEXT:    eor w0, w8, w1
     67 ; CHECK-NEXT:    ret
     68   %n0 = xor i8 %x, %y
     69   %n1 = and i8 %n0, 15
     70   %r = xor i8 %n1, %y
     71   ret i8 %r
     72 }
     73 
     74 define i16 @in16_constmask(i16 %x, i16 %y) {
     75 ; CHECK-LABEL: in16_constmask:
     76 ; CHECK:       // %bb.0:
     77 ; CHECK-NEXT:    eor w8, w0, w1
     78 ; CHECK-NEXT:    and w8, w8, #0xff
     79 ; CHECK-NEXT:    eor w0, w8, w1
     80 ; CHECK-NEXT:    ret
     81   %n0 = xor i16 %x, %y
     82   %n1 = and i16 %n0, 255
     83   %r = xor i16 %n1, %y
     84   ret i16 %r
     85 }
     86 
     87 define i32 @in32_constmask(i32 %x, i32 %y) {
     88 ; CHECK-LABEL: in32_constmask:
     89 ; CHECK:       // %bb.0:
     90 ; CHECK-NEXT:    eor w8, w0, w1
     91 ; CHECK-NEXT:    and w8, w8, #0xffff
     92 ; CHECK-NEXT:    eor w0, w8, w1
     93 ; CHECK-NEXT:    ret
     94   %n0 = xor i32 %x, %y
     95   %n1 = and i32 %n0, 65535
     96   %r = xor i32 %n1, %y
     97   ret i32 %r
     98 }
     99 
    100 define i64 @in64_constmask(i64 %x, i64 %y) {
    101 ; CHECK-LABEL: in64_constmask:
    102 ; CHECK:       // %bb.0:
    103 ; CHECK-NEXT:    eor w8, w0, w1
    104 ; CHECK-NEXT:    eor x0, x8, x1
    105 ; CHECK-NEXT:    ret
    106   %n0 = xor i64 %x, %y
    107   %n1 = and i64 %n0, 4294967295
    108   %r = xor i64 %n1, %y
    109   ret i64 %r
    110 }
    111 
    112 ; ============================================================================ ;
    113 ; Constant Commutativity tests.
    114 ; ============================================================================ ;
    115 
    116 define i32 @in_constmask_commutativity_0_1(i32 %x, i32 %y) {
    117 ; CHECK-LABEL: in_constmask_commutativity_0_1:
    118 ; CHECK:       // %bb.0:
    119 ; CHECK-NEXT:    eor w8, w0, w1
    120 ; CHECK-NEXT:    and w8, w8, #0xffff
    121 ; CHECK-NEXT:    eor w0, w1, w8
    122 ; CHECK-NEXT:    ret
    123   %n0 = xor i32 %x, %y
    124   %n1 = and i32 %n0, 65535
    125   %r = xor i32 %y, %n1 ; swapped
    126   ret i32 %r
    127 }
    128 
    129 define i32 @in_constmask_commutativity_1_0(i32 %x, i32 %y) {
    130 ; CHECK-LABEL: in_constmask_commutativity_1_0:
    131 ; CHECK:       // %bb.0:
    132 ; CHECK-NEXT:    eor w8, w0, w1
    133 ; CHECK-NEXT:    and w8, w8, #0xffff
    134 ; CHECK-NEXT:    eor w0, w8, w0
    135 ; CHECK-NEXT:    ret
    136   %n0 = xor i32 %x, %y
    137   %n1 = and i32 %n0, 65535
    138   %r = xor i32 %n1, %x ; %x instead of %y
    139   ret i32 %r
    140 }
    141 
    142 define i32 @in_constmask_commutativity_1_1(i32 %x, i32 %y) {
    143 ; CHECK-LABEL: in_constmask_commutativity_1_1:
    144 ; CHECK:       // %bb.0:
    145 ; CHECK-NEXT:    eor w8, w0, w1
    146 ; CHECK-NEXT:    and w8, w8, #0xffff
    147 ; CHECK-NEXT:    eor w0, w0, w8
    148 ; CHECK-NEXT:    ret
    149   %n0 = xor i32 %x, %y
    150   %n1 = and i32 %n0, 65535
    151   %r = xor i32 %x, %n1 ; swapped, %x instead of %y
    152   ret i32 %r
    153 }
    154 
    155 ; ============================================================================ ;
    156 ; Y is an 'and' too.
    157 ; ============================================================================ ;
    158 
    159 define i32 @in_complex_y0_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
    160 ; CHECK-LABEL: in_complex_y0_constmask:
    161 ; CHECK:       // %bb.0:
    162 ; CHECK-NEXT:    and w8, w1, w2
    163 ; CHECK-NEXT:    eor w9, w0, w8
    164 ; CHECK-NEXT:    and w9, w9, #0xffff
    165 ; CHECK-NEXT:    eor w0, w9, w8
    166 ; CHECK-NEXT:    ret
    167   %y = and i32 %y_hi, %y_low
    168   %n0 = xor i32 %x, %y
    169   %n1 = and i32 %n0, 65535
    170   %r = xor i32 %n1, %y
    171   ret i32 %r
    172 }
    173 
    174 define i32 @in_complex_y1_constmask(i32 %x, i32 %y_hi, i32 %y_low) {
    175 ; CHECK-LABEL: in_complex_y1_constmask:
    176 ; CHECK:       // %bb.0:
    177 ; CHECK-NEXT:    and w8, w1, w2
    178 ; CHECK-NEXT:    eor w9, w0, w8
    179 ; CHECK-NEXT:    and w9, w9, #0xffff
    180 ; CHECK-NEXT:    eor w0, w8, w9
    181 ; CHECK-NEXT:    ret
    182   %y = and i32 %y_hi, %y_low
    183   %n0 = xor i32 %x, %y
    184   %n1 = and i32 %n0, 65535
    185   %r = xor i32 %y, %n1
    186   ret i32 %r
    187 }
    188 
    189 ; ============================================================================ ;
    190 ; Negative tests. Should not be folded.
    191 ; ============================================================================ ;
    192 
    193 ; Multi-use tests.
    194 
    195 declare void @use32(i32) nounwind
    196 
    197 define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
    198 ; CHECK-LABEL: in_multiuse_A_constmask:
    199 ; CHECK:       // %bb.0:
    200 ; CHECK-NEXT:    str x20, [sp, #-32]! // 8-byte Folded Spill
    201 ; CHECK-NEXT:    eor w8, w0, w1
    202 ; CHECK-NEXT:    and w20, w8, #0xffff
    203 ; CHECK-NEXT:    mov w0, w20
    204 ; CHECK-NEXT:    stp x19, x30, [sp, #16] // 8-byte Folded Spill
    205 ; CHECK-NEXT:    mov w19, w1
    206 ; CHECK-NEXT:    bl use32
    207 ; CHECK-NEXT:    eor w0, w20, w19
    208 ; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 8-byte Folded Reload
    209 ; CHECK-NEXT:    ldr x20, [sp], #32 // 8-byte Folded Reload
    210 ; CHECK-NEXT:    ret
    211   %n0 = xor i32 %x, %y
    212   %n1 = and i32 %n0, 65535
    213   call void @use32(i32 %n1)
    214   %r = xor i32 %n1, %y
    215   ret i32 %r
    216 }
    217 
    218 define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
    219 ; CHECK-LABEL: in_multiuse_B_constmask:
    220 ; CHECK:       // %bb.0:
    221 ; CHECK-NEXT:    str x20, [sp, #-32]! // 8-byte Folded Spill
    222 ; CHECK-NEXT:    eor w0, w0, w1
    223 ; CHECK-NEXT:    stp x19, x30, [sp, #16] // 8-byte Folded Spill
    224 ; CHECK-NEXT:    mov w19, w1
    225 ; CHECK-NEXT:    and w20, w0, #0xffff
    226 ; CHECK-NEXT:    bl use32
    227 ; CHECK-NEXT:    eor w0, w20, w19
    228 ; CHECK-NEXT:    ldp x19, x30, [sp, #16] // 8-byte Folded Reload
    229 ; CHECK-NEXT:    ldr x20, [sp], #32 // 8-byte Folded Reload
    230 ; CHECK-NEXT:    ret
    231   %n0 = xor i32 %x, %y
    232   %n1 = and i32 %n0, 65535
    233   call void @use32(i32 %n0)
    234   %r = xor i32 %n1, %y
    235   ret i32 %r
    236 }
    237 
    238 ; Various bad variants
    239 
    240 define i32 @n0_badconstmask(i32 %x, i32 %y) {
    241 ; CHECK-LABEL: n0_badconstmask:
    242 ; CHECK:       // %bb.0:
    243 ; CHECK-NEXT:    and w8, w0, #0xffff
    244 ; CHECK-NEXT:    and w9, w1, #0xffff0001
    245 ; CHECK-NEXT:    orr w0, w8, w9
    246 ; CHECK-NEXT:    ret
    247   %mx = and i32 %x, 65535
    248   %my = and i32 %y, -65535 ; instead of -65536
    249   %r = or i32 %mx, %my
    250   ret i32 %r
    251 }
    252 
    253 define i32 @n1_thirdvar_constmask(i32 %x, i32 %y, i32 %z) {
    254 ; CHECK-LABEL: n1_thirdvar_constmask:
    255 ; CHECK:       // %bb.0:
    256 ; CHECK-NEXT:    eor w8, w0, w1
    257 ; CHECK-NEXT:    and w8, w8, #0xffff
    258 ; CHECK-NEXT:    eor w0, w8, w2
    259 ; CHECK-NEXT:    ret
    260   %n0 = xor i32 %x, %y
    261   %n1 = and i32 %n0, 65535
    262   %r = xor i32 %n1, %z ; instead of %y
    263   ret i32 %r
    264 }
    265