1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; fold (shl (zext (lshr (A, X))), X) -> (zext (shl (lshr (A, X)), X)) 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker; Canolicalize the sequence shl/zext/lshr performing the zeroextend 6*9880d681SAndroid Build Coastguard Worker; as the last instruction of the sequence. 7*9880d681SAndroid Build Coastguard Worker; This will help DAGCombiner to identify and then fold the sequence 8*9880d681SAndroid Build Coastguard Worker; of shifts into a single AND. 9*9880d681SAndroid Build Coastguard Worker; This transformation is profitable if the shift amounts are the same 10*9880d681SAndroid Build Coastguard Worker; and if there is only one use of the zext. 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdefine i16 @fun1(i8 zeroext %v) { 13*9880d681SAndroid Build Coastguard Workerentry: 14*9880d681SAndroid Build Coastguard Worker %shr = lshr i8 %v, 4 15*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %shr to i16 16*9880d681SAndroid Build Coastguard Worker %shl = shl i16 %ext, 4 17*9880d681SAndroid Build Coastguard Worker ret i16 %shl 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun1 21*9880d681SAndroid Build Coastguard Worker; CHECK: and 22*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 23*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 24*9880d681SAndroid Build Coastguard Worker; CHECK: ret 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerdefine i32 @fun2(i8 zeroext %v) { 27*9880d681SAndroid Build Coastguard Workerentry: 28*9880d681SAndroid Build Coastguard Worker %shr = lshr i8 %v, 4 29*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %shr to i32 30*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %ext, 4 31*9880d681SAndroid Build Coastguard Worker ret i32 %shl 32*9880d681SAndroid Build Coastguard Worker} 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun2 35*9880d681SAndroid Build Coastguard Worker; CHECK: and 36*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 37*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 38*9880d681SAndroid Build Coastguard Worker; CHECK: ret 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Workerdefine i32 @fun3(i16 zeroext %v) { 41*9880d681SAndroid Build Coastguard Workerentry: 42*9880d681SAndroid Build Coastguard Worker %shr = lshr i16 %v, 4 43*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %shr to i32 44*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %ext, 4 45*9880d681SAndroid Build Coastguard Worker ret i32 %shl 46*9880d681SAndroid Build Coastguard Worker} 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun3 49*9880d681SAndroid Build Coastguard Worker; CHECK: and 50*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 51*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 52*9880d681SAndroid Build Coastguard Worker; CHECK: ret 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerdefine i64 @fun4(i8 zeroext %v) { 55*9880d681SAndroid Build Coastguard Workerentry: 56*9880d681SAndroid Build Coastguard Worker %shr = lshr i8 %v, 4 57*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %shr to i64 58*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 59*9880d681SAndroid Build Coastguard Worker ret i64 %shl 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun4 63*9880d681SAndroid Build Coastguard Worker; CHECK: and 64*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 65*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 66*9880d681SAndroid Build Coastguard Worker; CHECK: ret 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Workerdefine i64 @fun5(i16 zeroext %v) { 69*9880d681SAndroid Build Coastguard Workerentry: 70*9880d681SAndroid Build Coastguard Worker %shr = lshr i16 %v, 4 71*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %shr to i64 72*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 73*9880d681SAndroid Build Coastguard Worker ret i64 %shl 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun5 77*9880d681SAndroid Build Coastguard Worker; CHECK: and 78*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 79*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 80*9880d681SAndroid Build Coastguard Worker; CHECK: ret 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workerdefine i64 @fun6(i32 zeroext %v) { 83*9880d681SAndroid Build Coastguard Workerentry: 84*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %v, 4 85*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %shr to i64 86*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 87*9880d681SAndroid Build Coastguard Worker ret i64 %shl 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun6 91*9880d681SAndroid Build Coastguard Worker; CHECK: and 92*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 93*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 94*9880d681SAndroid Build Coastguard Worker; CHECK: ret 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker; Don't fold the pattern if we use arithmetic shifts. 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerdefine i64 @fun7(i8 zeroext %v) { 99*9880d681SAndroid Build Coastguard Workerentry: 100*9880d681SAndroid Build Coastguard Worker %shr = ashr i8 %v, 4 101*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %shr to i64 102*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 103*9880d681SAndroid Build Coastguard Worker ret i64 %shl 104*9880d681SAndroid Build Coastguard Worker} 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun7 107*9880d681SAndroid Build Coastguard Worker; CHECK: sar 108*9880d681SAndroid Build Coastguard Worker; CHECK: shl 109*9880d681SAndroid Build Coastguard Worker; CHECK: ret 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workerdefine i64 @fun8(i16 zeroext %v) { 112*9880d681SAndroid Build Coastguard Workerentry: 113*9880d681SAndroid Build Coastguard Worker %shr = ashr i16 %v, 4 114*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %shr to i64 115*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 116*9880d681SAndroid Build Coastguard Worker ret i64 %shl 117*9880d681SAndroid Build Coastguard Worker} 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun8 120*9880d681SAndroid Build Coastguard Worker; CHECK: sar 121*9880d681SAndroid Build Coastguard Worker; CHECK: shl 122*9880d681SAndroid Build Coastguard Worker; CHECK: ret 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workerdefine i64 @fun9(i32 zeroext %v) { 125*9880d681SAndroid Build Coastguard Workerentry: 126*9880d681SAndroid Build Coastguard Worker %shr = ashr i32 %v, 4 127*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %shr to i64 128*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 129*9880d681SAndroid Build Coastguard Worker ret i64 %shl 130*9880d681SAndroid Build Coastguard Worker} 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun9 133*9880d681SAndroid Build Coastguard Worker; CHECK: sar 134*9880d681SAndroid Build Coastguard Worker; CHECK: shl 135*9880d681SAndroid Build Coastguard Worker; CHECK: ret 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Worker; Don't fold the pattern if there is more than one use of the 138*9880d681SAndroid Build Coastguard Worker; operand in input to the shift left. 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Workerdefine i64 @fun10(i8 zeroext %v) { 141*9880d681SAndroid Build Coastguard Workerentry: 142*9880d681SAndroid Build Coastguard Worker %shr = lshr i8 %v, 4 143*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %shr to i64 144*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 145*9880d681SAndroid Build Coastguard Worker %add = add i64 %shl, %ext 146*9880d681SAndroid Build Coastguard Worker ret i64 %add 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun10 150*9880d681SAndroid Build Coastguard Worker; CHECK: shr 151*9880d681SAndroid Build Coastguard Worker; CHECK: shl 152*9880d681SAndroid Build Coastguard Worker; CHECK: ret 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Workerdefine i64 @fun11(i16 zeroext %v) { 155*9880d681SAndroid Build Coastguard Workerentry: 156*9880d681SAndroid Build Coastguard Worker %shr = lshr i16 %v, 4 157*9880d681SAndroid Build Coastguard Worker %ext = zext i16 %shr to i64 158*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 159*9880d681SAndroid Build Coastguard Worker %add = add i64 %shl, %ext 160*9880d681SAndroid Build Coastguard Worker ret i64 %add 161*9880d681SAndroid Build Coastguard Worker} 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun11 164*9880d681SAndroid Build Coastguard Worker; CHECK: shr 165*9880d681SAndroid Build Coastguard Worker; CHECK: shl 166*9880d681SAndroid Build Coastguard Worker; CHECK: ret 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Workerdefine i64 @fun12(i32 zeroext %v) { 169*9880d681SAndroid Build Coastguard Workerentry: 170*9880d681SAndroid Build Coastguard Worker %shr = lshr i32 %v, 4 171*9880d681SAndroid Build Coastguard Worker %ext = zext i32 %shr to i64 172*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %ext, 4 173*9880d681SAndroid Build Coastguard Worker %add = add i64 %shl, %ext 174*9880d681SAndroid Build Coastguard Worker ret i64 %add 175*9880d681SAndroid Build Coastguard Worker} 176*9880d681SAndroid Build Coastguard Worker 177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @fun12 178*9880d681SAndroid Build Coastguard Worker; CHECK: shr 179*9880d681SAndroid Build Coastguard Worker; CHECK: shl 180*9880d681SAndroid Build Coastguard Worker; CHECK: ret 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Worker; PR17380 183*9880d681SAndroid Build Coastguard Worker; Make sure that the combined dags are legal if we run the DAGCombiner after 184*9880d681SAndroid Build Coastguard Worker; Legalization took place. The add instruction is redundant and increases by 185*9880d681SAndroid Build Coastguard Worker; one the number of uses of the zext. This prevents the transformation from 186*9880d681SAndroid Build Coastguard Worker; firing before dags are legalized and optimized. 187*9880d681SAndroid Build Coastguard Worker; Once the add is removed, the number of uses becomes one and therefore the 188*9880d681SAndroid Build Coastguard Worker; dags are canonicalized. After Legalization, we need to make sure that the 189*9880d681SAndroid Build Coastguard Worker; valuetype for the shift count is legal. 190*9880d681SAndroid Build Coastguard Worker; Verify also that we correctly fold the shl-shr sequence into an 191*9880d681SAndroid Build Coastguard Worker; AND with bitmask. 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Workerdefine void @g(i32 %a) { 194*9880d681SAndroid Build Coastguard Worker %b = lshr i32 %a, 2 195*9880d681SAndroid Build Coastguard Worker %c = zext i32 %b to i64 196*9880d681SAndroid Build Coastguard Worker %d = add i64 %c, 1 197*9880d681SAndroid Build Coastguard Worker %e = shl i64 %c, 2 198*9880d681SAndroid Build Coastguard Worker tail call void @f(i64 %e) 199*9880d681SAndroid Build Coastguard Worker ret void 200*9880d681SAndroid Build Coastguard Worker} 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @g 203*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shr 204*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: shl 205*9880d681SAndroid Build Coastguard Worker; CHECK: and 206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jmp 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Workerdeclare void @f(i64) 209*9880d681SAndroid Build Coastguard Worker 210