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