201 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Given pattern:5; (trunc (iSrc x a>> Q) to iDst) a>> K6; we should rewrite it as7; (trunc (iSrc x a>> (Q+K)) to iDst)8; iff (Q+K) is bitwidth(iSrc)-19; THIS FOLD DOES *NOT* REQUIRE ANY 'nuw'/`nsw` FLAGS!10 11; Basic scalar test12 13define i16 @t0(i32 %x, i16 %y) {14; CHECK-LABEL: @t0(15; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 3116; CHECK-NEXT: [[T5:%.*]] = trunc nsw i32 [[TMP1]] to i1617; CHECK-NEXT: ret i16 [[T5]]18;19 %t0 = sub i16 32, %y20 %t1 = zext i16 %t0 to i3221 %t2 = ashr i32 %x, %t122 %t3 = trunc i32 %t2 to i1623 %t4 = add i16 %y, -124 %t5 = ashr i16 %t3, %t425 ret i16 %t526}27 28; Basic vector tests29 30define <2 x i16> @t1_vec_splat(<2 x i32> %x, <2 x i16> %y) {31; CHECK-LABEL: @t1_vec_splat(32; CHECK-NEXT: [[TMP1:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 31)33; CHECK-NEXT: [[T5:%.*]] = trunc nsw <2 x i32> [[TMP1]] to <2 x i16>34; CHECK-NEXT: ret <2 x i16> [[T5]]35;36 %t0 = sub <2 x i16> <i16 32, i16 32>, %y37 %t1 = zext <2 x i16> %t0 to <2 x i32>38 %t2 = ashr <2 x i32> %x, %t139 %t3 = trunc <2 x i32> %t2 to <2 x i16>40 %t4 = add <2 x i16> %y, <i16 -1, i16 -1>41 %t5 = ashr <2 x i16> %t3, %t442 ret <2 x i16> %t543}44 45define <3 x i16> @t3_vec_nonsplat_poison0(<3 x i32> %x, <3 x i16> %y) {46; CHECK-LABEL: @t3_vec_nonsplat_poison0(47; CHECK-NEXT: [[TMP1:%.*]] = ashr <3 x i32> [[X:%.*]], <i32 31, i32 poison, i32 31>48; CHECK-NEXT: [[T5:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i16>49; CHECK-NEXT: ret <3 x i16> [[T5]]50;51 %t0 = sub <3 x i16> <i16 32, i16 poison, i16 32>, %y52 %t1 = zext <3 x i16> %t0 to <3 x i32>53 %t2 = ashr <3 x i32> %x, %t154 %t3 = trunc <3 x i32> %t2 to <3 x i16>55 %t4 = add <3 x i16> %y, <i16 -1, i16 -1, i16 -1>56 %t5 = ashr <3 x i16> %t3, %t457 ret <3 x i16> %t558}59 60define <3 x i16> @t4_vec_nonsplat_poison1(<3 x i32> %x, <3 x i16> %y) {61; CHECK-LABEL: @t4_vec_nonsplat_poison1(62; CHECK-NEXT: [[TMP1:%.*]] = ashr <3 x i32> [[X:%.*]], <i32 31, i32 poison, i32 31>63; CHECK-NEXT: [[T5:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i16>64; CHECK-NEXT: ret <3 x i16> [[T5]]65;66 %t0 = sub <3 x i16> <i16 32, i16 32, i16 32>, %y67 %t1 = zext <3 x i16> %t0 to <3 x i32>68 %t2 = ashr <3 x i32> %x, %t169 %t3 = trunc <3 x i32> %t2 to <3 x i16>70 %t4 = add <3 x i16> %y, <i16 -1, i16 poison, i16 -1>71 %t5 = ashr <3 x i16> %t3, %t472 ret <3 x i16> %t573}74 75define <3 x i16> @t5_vec_nonsplat_poison1(<3 x i32> %x, <3 x i16> %y) {76; CHECK-LABEL: @t5_vec_nonsplat_poison1(77; CHECK-NEXT: [[TMP1:%.*]] = ashr <3 x i32> [[X:%.*]], <i32 31, i32 poison, i32 31>78; CHECK-NEXT: [[T5:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i16>79; CHECK-NEXT: ret <3 x i16> [[T5]]80;81 %t0 = sub <3 x i16> <i16 32, i16 poison, i16 32>, %y82 %t1 = zext <3 x i16> %t0 to <3 x i32>83 %t2 = ashr <3 x i32> %x, %t184 %t3 = trunc <3 x i32> %t2 to <3 x i16>85 %t4 = add <3 x i16> %y, <i16 -1, i16 poison, i16 -1>86 %t5 = ashr <3 x i16> %t3, %t487 ret <3 x i16> %t588}89 90; One-use tests91 92declare void @use16(i16)93declare void @use32(i32)94 95define i16 @t6_extrause0(i32 %x, i16 %y) {96; CHECK-LABEL: @t6_extrause0(97; CHECK-NEXT: [[T0:%.*]] = sub i16 32, [[Y:%.*]]98; CHECK-NEXT: [[T1:%.*]] = zext nneg i16 [[T0]] to i3299; CHECK-NEXT: [[T2:%.*]] = ashr i32 [[X:%.*]], [[T1]]100; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[T2]] to i16101; CHECK-NEXT: call void @use16(i16 [[T3]])102; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X]], 31103; CHECK-NEXT: [[T5:%.*]] = trunc nsw i32 [[TMP1]] to i16104; CHECK-NEXT: ret i16 [[T5]]105;106 %t0 = sub i16 32, %y107 %t1 = zext i16 %t0 to i32108 %t2 = ashr i32 %x, %t1109 %t3 = trunc i32 %t2 to i16110 %t4 = add i16 %y, -1111 call void @use16(i16 %t3)112 %t5 = ashr i16 %t3, %t4113 ret i16 %t5114}115 116define i16 @t7_extrause1(i32 %x, i16 %y) {117; CHECK-LABEL: @t7_extrause1(118; CHECK-NEXT: [[T4:%.*]] = add i16 [[Y:%.*]], -1119; CHECK-NEXT: call void @use16(i16 [[T4]])120; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 31121; CHECK-NEXT: [[T5:%.*]] = trunc nsw i32 [[TMP1]] to i16122; CHECK-NEXT: ret i16 [[T5]]123;124 %t0 = sub i16 32, %y125 %t1 = zext i16 %t0 to i32126 %t2 = ashr i32 %x, %t1127 %t3 = trunc i32 %t2 to i16128 %t4 = add i16 %y, -1129 call void @use16(i16 %t4)130 %t5 = ashr i16 %t3, %t4131 ret i16 %t5132}133 134define i16 @t8_extrause2(i32 %x, i16 %y) {135; CHECK-LABEL: @t8_extrause2(136; CHECK-NEXT: [[T0:%.*]] = sub i16 32, [[Y:%.*]]137; CHECK-NEXT: [[T1:%.*]] = zext nneg i16 [[T0]] to i32138; CHECK-NEXT: [[T2:%.*]] = ashr i32 [[X:%.*]], [[T1]]139; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[T2]] to i16140; CHECK-NEXT: [[T4:%.*]] = add i16 [[Y]], -1141; CHECK-NEXT: call void @use16(i16 [[T3]])142; CHECK-NEXT: call void @use16(i16 [[T4]])143; CHECK-NEXT: [[T5:%.*]] = ashr i16 [[T3]], [[T4]]144; CHECK-NEXT: ret i16 [[T5]]145;146 %t0 = sub i16 32, %y147 %t1 = zext i16 %t0 to i32148 %t2 = ashr i32 %x, %t1149 %t3 = trunc i32 %t2 to i16150 %t4 = add i16 %y, -1151 call void @use16(i16 %t3)152 call void @use16(i16 %t4)153 %t5 = ashr i16 %t3, %t4154 ret i16 %t5155}156 157; No 'nuw'/'nsw' flags are to be propagated!158; But we can't test that, such IR does not reach that code.159 160; Negative tests161 162; Can only fold if we are extracting the sign bit.163define i16 @t9_ashr(i32 %x, i16 %y) {164; CHECK-LABEL: @t9_ashr(165; CHECK-NEXT: [[T0:%.*]] = sub i16 32, [[Y:%.*]]166; CHECK-NEXT: [[T1:%.*]] = zext nneg i16 [[T0]] to i32167; CHECK-NEXT: [[T2:%.*]] = ashr i32 [[X:%.*]], [[T1]]168; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[T2]] to i16169; CHECK-NEXT: [[T4:%.*]] = add i16 [[Y]], -2170; CHECK-NEXT: [[T5:%.*]] = ashr i16 [[T3]], [[T4]]171; CHECK-NEXT: ret i16 [[T5]]172;173 %t0 = sub i16 32, %y174 %t1 = zext i16 %t0 to i32175 %t2 = ashr i32 %x, %t1176 %t3 = trunc i32 %t2 to i16177 %t4 = add i16 %y, -2178 %t5 = ashr i16 %t3, %t4179 ret i16 %t5180}181 182; If we have different right-shifts, in general, we can't do anything with it.183define i16 @n10_lshr_ashr(i32 %x, i16 %y) {184; CHECK-LABEL: @n10_lshr_ashr(185; CHECK-NEXT: [[T0:%.*]] = sub i16 32, [[Y:%.*]]186; CHECK-NEXT: [[T1:%.*]] = zext nneg i16 [[T0]] to i32187; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[X:%.*]], [[T1]]188; CHECK-NEXT: [[T3:%.*]] = trunc i32 [[T2]] to i16189; CHECK-NEXT: [[T4:%.*]] = add i16 [[Y]], -1190; CHECK-NEXT: [[T5:%.*]] = ashr i16 [[T3]], [[T4]]191; CHECK-NEXT: ret i16 [[T5]]192;193 %t0 = sub i16 32, %y194 %t1 = zext i16 %t0 to i32195 %t2 = lshr i32 %x, %t1196 %t3 = trunc i32 %t2 to i16197 %t4 = add i16 %y, -1198 %t5 = ashr i16 %t3, %t4199 ret i16 %t5200}201