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