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