Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=generic | FileCheck %s
      2 
      3 ; Check that we recognize this idiom for rotation too:
      4 ;    a << (b & (OpSize-1)) | a >> ((0 - b) & (OpSize-1))
      5 
      6 define i32 @rotate_left_32(i32 %a, i32 %b) {
      7 ; CHECK-LABEL: rotate_left_32:
      8 ; CHECK-NOT: and
      9 ; CHECK: roll
     10 entry:
     11   %and = and i32 %b, 31
     12   %shl = shl i32 %a, %and
     13   %0 = sub i32 0, %b
     14   %and3 = and i32 %0, 31
     15   %shr = lshr i32 %a, %and3
     16   %or = or i32 %shl, %shr
     17   ret i32 %or
     18 }
     19 
     20 define i32 @rotate_right_32(i32 %a, i32 %b) {
     21 ; CHECK-LABEL: rotate_right_32:
     22 ; CHECK-NOT: and
     23 ; CHECK: rorl
     24 entry:
     25   %and = and i32 %b, 31
     26   %shl = lshr i32 %a, %and
     27   %0 = sub i32 0, %b
     28   %and3 = and i32 %0, 31
     29   %shr = shl i32 %a, %and3
     30   %or = or i32 %shl, %shr
     31   ret i32 %or
     32 }
     33 
     34 define i64 @rotate_left_64(i64 %a, i64 %b) {
     35 ; CHECK-LABEL: rotate_left_64:
     36 ; CHECK-NOT: and
     37 ; CHECK: rolq
     38 entry:
     39   %and = and i64 %b, 63
     40   %shl = shl i64 %a, %and
     41   %0 = sub i64 0, %b
     42   %and3 = and i64 %0, 63
     43   %shr = lshr i64 %a, %and3
     44   %or = or i64 %shl, %shr
     45   ret i64 %or
     46 }
     47 
     48 define i64 @rotate_right_64(i64 %a, i64 %b) {
     49 ; CHECK-LABEL: rotate_right_64:
     50 ; CHECK-NOT: and
     51 ; CHECK: rorq
     52 entry:
     53   %and = and i64 %b, 63
     54   %shl = lshr i64 %a, %and
     55   %0 = sub i64 0, %b
     56   %and3 = and i64 %0, 63
     57   %shr = shl i64 %a, %and3
     58   %or = or i64 %shl, %shr
     59   ret i64 %or
     60 }
     61 
     62 ; Also check mem operand.
     63 
     64 define void @rotate_left_m32(i32 *%pa, i32 %b) {
     65 ; CHECK-LABEL: rotate_left_m32:
     66 ; CHECK-NOT: and
     67 ; CHECK: roll
     68 ; no store:
     69 ; CHECK-NOT: mov
     70 entry:
     71   %a = load i32, i32* %pa, align 16
     72   %and = and i32 %b, 31
     73   %shl = shl i32 %a, %and
     74   %0 = sub i32 0, %b
     75   %and3 = and i32 %0, 31
     76   %shr = lshr i32 %a, %and3
     77   %or = or i32 %shl, %shr
     78   store i32 %or, i32* %pa, align 32
     79   ret void
     80 }
     81 
     82 define void @rotate_right_m32(i32 *%pa, i32 %b) {
     83 ; CHECK-LABEL: rotate_right_m32:
     84 ; CHECK-NOT: and
     85 ; CHECK: rorl
     86 ; no store:
     87 ; CHECK-NOT: mov
     88 entry:
     89   %a = load i32, i32* %pa, align 16
     90   %and = and i32 %b, 31
     91   %shl = lshr i32 %a, %and
     92   %0 = sub i32 0, %b
     93   %and3 = and i32 %0, 31
     94   %shr = shl i32 %a, %and3
     95   %or = or i32 %shl, %shr
     96   store i32 %or, i32* %pa, align 32
     97   ret void
     98 }
     99 
    100 define void @rotate_left_m64(i64 *%pa, i64 %b) {
    101 ; CHECK-LABEL: rotate_left_m64:
    102 ; CHECK-NOT: and
    103 ; CHECK: rolq
    104 ; no store:
    105 ; CHECK-NOT: mov
    106 entry:
    107   %a = load i64, i64* %pa, align 16
    108   %and = and i64 %b, 63
    109   %shl = shl i64 %a, %and
    110   %0 = sub i64 0, %b
    111   %and3 = and i64 %0, 63
    112   %shr = lshr i64 %a, %and3
    113   %or = or i64 %shl, %shr
    114   store i64 %or, i64* %pa, align 64
    115   ret void
    116 }
    117 
    118 define void @rotate_right_m64(i64 *%pa, i64 %b) {
    119 ; CHECK-LABEL: rotate_right_m64:
    120 ; CHECK-NOT: and
    121 ; CHECK: rorq
    122 ; no store:
    123 ; CHECK-NOT: mov
    124 entry:
    125   %a = load i64, i64* %pa, align 16
    126   %and = and i64 %b, 63
    127   %shl = lshr i64 %a, %and
    128   %0 = sub i64 0, %b
    129   %and3 = and i64 %0, 63
    130   %shr = shl i64 %a, %and3
    131   %or = or i64 %shl, %shr
    132   store i64 %or, i64* %pa, align 64
    133   ret void
    134 }
    135