Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
      3 
      4 ; Various tests for ands that should be implemented with movzx, but aren't due
      5 ; demanded bits shortcomings.
      6 
      7 ; The backend will insert a zext to promote the shift to i32.
      8 define i16 @test1(i16 %x) {
      9 ; CHECK-LABEL: test1:
     10 ; CHECK:       # %bb.0:
     11 ; CHECK-NEXT:    movzwl %di, %eax
     12 ; CHECK-NEXT:    shrl %eax
     13 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
     14 ; CHECK-NEXT:    retq
     15   %y = lshr i16 %x, 1
     16   ret i16 %y
     17 }
     18 
     19 define i32 @test2(i32 %x) {
     20 ; CHECK-LABEL: test2:
     21 ; CHECK:       # %bb.0:
     22 ; CHECK-NEXT:    movzwl %di, %eax
     23 ; CHECK-NEXT:    shrl %eax
     24 ; CHECK-NEXT:    retq
     25   %y = and i32 %x, 65535
     26   %z = lshr i32 %y, 1
     27   ret i32 %z
     28 }
     29 
     30 define i32 @test3(i32 %x) {
     31 ; CHECK-LABEL: test3:
     32 ; CHECK:       # %bb.0:
     33 ; CHECK-NEXT:    movzbl %dil, %eax
     34 ; CHECK-NEXT:    shrl %eax
     35 ; CHECK-NEXT:    retq
     36   %y = and i32 %x, 255
     37   %z = lshr i32 %y, 1
     38   ret i32 %z
     39 }
     40 
     41 define i16 @test4(i16 %x) {
     42 ; CHECK-LABEL: test4:
     43 ; CHECK:       # %bb.0:
     44 ; CHECK-NEXT:    movzbl %dil, %eax
     45 ; CHECK-NEXT:    shrl %eax
     46 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
     47 ; CHECK-NEXT:    retq
     48   %y = and i16 %x, 255
     49   %z = lshr i16 %y, 1
     50   ret i16 %z
     51 }
     52 
     53 define i16 @test5(i16 %x) {
     54 ; CHECK-LABEL: test5:
     55 ; CHECK:       # %bb.0:
     56 ; CHECK-NEXT:    movzwl %di, %eax
     57 ; CHECK-NEXT:    shrl $9, %eax
     58 ; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
     59 ; CHECK-NEXT:    retq
     60   %y = lshr i16 %x, 9
     61   ret i16 %y
     62 }
     63 
     64 define i32 @test6(i32 %x) {
     65 ; CHECK-LABEL: test6:
     66 ; CHECK:       # %bb.0:
     67 ; CHECK-NEXT:    movzwl %di, %eax
     68 ; CHECK-NEXT:    shrl $9, %eax
     69 ; CHECK-NEXT:    retq
     70   %y = and i32 %x, 65535
     71   %z = lshr i32 %y, 9
     72   ret i32 %z
     73 }
     74 
     75 ; TODO: We could turn this and into a zero extend.
     76 define i32 @test7(i32 %x) {
     77 ; CHECK-LABEL: test7:
     78 ; CHECK:       # %bb.0:
     79 ; CHECK-NEXT:    orl $1, %edi
     80 ; CHECK-NEXT:    movzwl %di, %eax
     81 ; CHECK-NEXT:    retq
     82   %y = and i32 %x, 65534
     83   %z = or i32 %y, 1
     84   ret i32 %z
     85 }
     86 
     87 ; We actually get a movzx on this one, but only because we canonicalize the and
     88 ; after the or before SimplifyDemandedBits messes it up.
     89 define i32 @test8(i32 %x) {
     90 ; CHECK-LABEL: test8:
     91 ; CHECK:       # %bb.0:
     92 ; CHECK-NEXT:    orl $1, %edi
     93 ; CHECK-NEXT:    movzwl %di, %eax
     94 ; CHECK-NEXT:    retq
     95   %y = and i32 %x, 65535
     96   %z = or i32 %y, 1
     97   ret i32 %z
     98 }
     99 
    100 define i64 @add_neg_one(i64 %x) {
    101 ; CHECK-LABEL: add_neg_one:
    102 ; CHECK:       # %bb.0:
    103 ; CHECK-NEXT:    leal -1(%rdi), %eax
    104 ; CHECK-NEXT:    andl %edi, %eax
    105 ; CHECK-NEXT:    movzwl %ax, %eax
    106 ; CHECK-NEXT:    retq
    107   %a1 = and i64 %x, 65535
    108   %a2 = add i64 %x, 65535
    109   %r = and i64 %a1, %a2
    110   ret i64 %r
    111 }
    112 
    113 define i64 @sub_neg_one(i64 %x) {
    114 ; CHECK-LABEL: sub_neg_one:
    115 ; CHECK:       # %bb.0:
    116 ; CHECK-NEXT:    leal -65535(%rdi), %eax
    117 ; CHECK-NEXT:    andl %edi, %eax
    118 ; CHECK-NEXT:    movzwl %ax, %eax
    119 ; CHECK-NEXT:    retq
    120   %a1 = and i64 %x, 65535
    121   %a2 = sub i64 %x, 65535
    122   %r = and i64 %a1, %a2
    123   ret i64 %r
    124 }
    125 
    126 define i64 @mul_neg_one(i64 %x) {
    127 ; CHECK-LABEL: mul_neg_one:
    128 ; CHECK:       # %bb.0:
    129 ; CHECK-NEXT:    movl %edi, %eax
    130 ; CHECK-NEXT:    negl %eax
    131 ; CHECK-NEXT:    andl %edi, %eax
    132 ; CHECK-NEXT:    movzwl %ax, %eax
    133 ; CHECK-NEXT:    retq
    134   %a1 = and i64 %x, 65535
    135   %a2 = mul i64 %x, 65535
    136   %r = and i64 %a1, %a2
    137   ret i64 %r
    138 }
    139 
    140 define i32 @PR36689(i32*) {
    141 ; CHECK-LABEL: PR36689:
    142 ; CHECK:       # %bb.0:
    143 ; CHECK-NEXT:    movzwl (%rdi), %eax
    144 ; CHECK-NEXT:    orl $255, %eax
    145 ; CHECK-NEXT:    retq
    146   %2 = load i32, i32* %0
    147   %3 = and i32 %2, 65280
    148   %4 = or i32 %3, 255
    149   ret i32 %4
    150 }
    151