160 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s3 4define i16 @shl_1(i8 %x) {5; CHECK-LABEL: @shl_1(6; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i167; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[ZEXT]], 18; CHECK-NEXT: ret i16 [[SHL]]9;10 %zext = zext i8 %x to i3211 %shl = shl i32 %zext, 112 %trunc = trunc i32 %shl to i1613 ret i16 %trunc14}15 16define i16 @shl_15(i8 %x) {17; CHECK-LABEL: @shl_15(18; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i1619; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[ZEXT]], 1520; CHECK-NEXT: ret i16 [[SHL]]21;22 %zext = zext i8 %x to i3223 %shl = shl i32 %zext, 1524 %trunc = trunc i32 %shl to i1625 ret i16 %trunc26}27 28; Negative test - shift amount isn't less than target bitwidth29 30define i16 @shl_16(i8 %x) {31; CHECK-LABEL: @shl_16(32; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i3233; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ZEXT]], 1634; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHL]] to i1635; CHECK-NEXT: ret i16 [[TRUNC]]36;37 %zext = zext i8 %x to i3238 %shl = shl i32 %zext, 1639 %trunc = trunc i32 %shl to i1640 ret i16 %trunc41}42 43; Negative test -- variable shift amount44 45define i16 @shl_var_shift_amount(i8 %x, i8 %y) {46; CHECK-LABEL: @shl_var_shift_amount(47; CHECK-NEXT: [[ZEXT_X:%.*]] = zext i8 [[X:%.*]] to i3248; CHECK-NEXT: [[ZEXT_Y:%.*]] = zext i8 [[Y:%.*]] to i3249; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[ZEXT_X]], [[ZEXT_Y]]50; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHL]] to i1651; CHECK-NEXT: ret i16 [[TRUNC]]52;53 %zext.x = zext i8 %x to i3254 %zext.y = zext i8 %y to i3255 %shl = shl i32 %zext.x, %zext.y56 %trunc = trunc i32 %shl to i1657 ret i16 %trunc58}59 60define i16 @shl_var_bounded_shift_amount(i8 %x, i8 %y) {61; CHECK-LABEL: @shl_var_bounded_shift_amount(62; CHECK-NEXT: [[ZEXT_X:%.*]] = zext i8 [[X:%.*]] to i1663; CHECK-NEXT: [[ZEXT_Y:%.*]] = zext i8 [[Y:%.*]] to i1664; CHECK-NEXT: [[AND:%.*]] = and i16 [[ZEXT_Y]], 1565; CHECK-NEXT: [[SHL:%.*]] = shl i16 [[ZEXT_X]], [[AND]]66; CHECK-NEXT: ret i16 [[SHL]]67;68 %zext.x = zext i8 %x to i3269 %zext.y = zext i8 %y to i3270 %and = and i32 %zext.y, 1571 %shl = shl i32 %zext.x, %and72 %trunc = trunc i32 %shl to i1673 ret i16 %trunc74}75 76; Negative test (https://reviews.llvm.org/D108091#2950930)77 78define i32 @shl_check_no_overflow(i32 %x, i16 %amt) {79; CHECK-LABEL: @shl_check_no_overflow(80; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[X:%.*]] to i6481; CHECK-NEXT: [[SEXT:%.*]] = sext i16 [[AMT:%.*]] to i6482; CHECK-NEXT: [[AND:%.*]] = and i64 [[SEXT]], 429496729583; CHECK-NEXT: [[SHL:%.*]] = shl i64 [[ZEXT]], [[AND]]84; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[SHL]] to i3285; CHECK-NEXT: ret i32 [[TRUNC]]86;87 %zext = zext i32 %x to i6488 %sext = sext i16 %amt to i6489 %and = and i64 %sext, 429496729590 %shl = shl i64 %zext, %and91 %trunc = trunc i64 %shl to i3292 ret i32 %trunc93}94 95define <2 x i16> @shl_vector(<2 x i8> %x) {96; CHECK-LABEL: @shl_vector(97; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>98; CHECK-NEXT: [[S:%.*]] = shl <2 x i16> [[Z]], <i16 4, i16 10>99; CHECK-NEXT: ret <2 x i16> [[S]]100;101 %z = zext <2 x i8> %x to <2 x i32>102 %s = shl <2 x i32> %z, <i32 4, i32 10>103 %t = trunc <2 x i32> %s to <2 x i16>104 ret <2 x i16> %t105}106 107; Negative test - can only fold to <2 x i16>, requiring new vector type108 109define <2 x i8> @shl_vector_no_new_vector_type(<2 x i8> %x) {110; CHECK-LABEL: @shl_vector_no_new_vector_type(111; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>112; CHECK-NEXT: [[S:%.*]] = shl <2 x i32> [[Z]], <i32 4, i32 10>113; CHECK-NEXT: [[T:%.*]] = trunc <2 x i32> [[S]] to <2 x i8>114; CHECK-NEXT: ret <2 x i8> [[T]]115;116 %z = zext <2 x i8> %x to <2 x i32>117 %s = shl <2 x i32> %z, <i32 4, i32 10>118 %t = trunc <2 x i32> %s to <2 x i8>119 ret <2 x i8> %t120}121 122; Negative test123 124define <2 x i16> @shl_vector_large_shift_amount(<2 x i8> %x) {125; CHECK-LABEL: @shl_vector_large_shift_amount(126; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i32>127; CHECK-NEXT: [[S:%.*]] = shl <2 x i32> [[Z]], <i32 16, i32 5>128; CHECK-NEXT: [[T:%.*]] = trunc <2 x i32> [[S]] to <2 x i16>129; CHECK-NEXT: ret <2 x i16> [[T]]130;131 %z = zext <2 x i8> %x to <2 x i32>132 %s = shl <2 x i32> %z, <i32 16, i32 5>133 %t = trunc <2 x i32> %s to <2 x i16>134 ret <2 x i16> %t135}136 137define i16 @shl_nuw(i8 %x) {138; CHECK-LABEL: @shl_nuw(139; CHECK-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16140; CHECK-NEXT: [[S:%.*]] = shl i16 [[Z]], 15141; CHECK-NEXT: ret i16 [[S]]142;143 %z = zext i8 %x to i32144 %s = shl nuw i32 %z, 15145 %t = trunc i32 %s to i16146 ret i16 %t147}148 149define i16 @shl_nsw(i8 %x) {150; CHECK-LABEL: @shl_nsw(151; CHECK-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16152; CHECK-NEXT: [[S:%.*]] = shl i16 [[Z]], 15153; CHECK-NEXT: ret i16 [[S]]154;155 %z = zext i8 %x to i32156 %s = shl nsw i32 %z, 15157 %t = trunc i32 %s to i16158 ret i16 %t159}160