; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instcombine -data-layout="n8:16:32" -S | FileCheck %s --check-prefix=ALL --check-prefix=LEGAL8 ; RUN: opt < %s -instcombine -data-layout="n16" -S | FileCheck %s --check-prefix=ALL --check-prefix=LEGAL16 ; PR35792 - https://bugs.llvm.org/show_bug.cgi?id=35792 define i16 @zext_add(i8 %x) { ; LEGAL8-LABEL: @zext_add( ; LEGAL8-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 44 ; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] ; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 ; LEGAL8-NEXT: ret i16 [[R]] ; ; LEGAL16-LABEL: @zext_add( ; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 ; LEGAL16-NEXT: [[B:%.*]] = add nuw nsw i16 [[Z]], 44 ; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]] ; LEGAL16-NEXT: ret i16 [[R]] ; %z = zext i8 %x to i16 %b = add i16 %z, 44 %r = and i16 %b, %z ret i16 %r } define i16 @zext_sub(i8 %x) { ; LEGAL8-LABEL: @zext_sub( ; LEGAL8-NEXT: [[TMP1:%.*]] = sub i8 -5, [[X:%.*]] ; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] ; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 ; LEGAL8-NEXT: ret i16 [[R]] ; ; LEGAL16-LABEL: @zext_sub( ; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 ; LEGAL16-NEXT: [[B:%.*]] = sub nsw i16 251, [[Z]] ; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]] ; LEGAL16-NEXT: ret i16 [[R]] ; %z = zext i8 %x to i16 %b = sub i16 -5, %z %r = and i16 %b, %z ret i16 %r } define i16 @zext_mul(i8 %x) { ; LEGAL8-LABEL: @zext_mul( ; LEGAL8-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 3 ; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] ; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 ; LEGAL8-NEXT: ret i16 [[R]] ; ; LEGAL16-LABEL: @zext_mul( ; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 ; LEGAL16-NEXT: [[B:%.*]] = mul nuw nsw i16 [[Z]], 3 ; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]] ; LEGAL16-NEXT: ret i16 [[R]] ; %z = zext i8 %x to i16 %b = mul i16 %z, 3 %r = and i16 %b, %z ret i16 %r } define i16 @zext_lshr(i8 %x) { ; LEGAL8-LABEL: @zext_lshr( ; LEGAL8-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 4 ; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] ; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 ; LEGAL8-NEXT: ret i16 [[R]] ; ; LEGAL16-LABEL: @zext_lshr( ; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 ; LEGAL16-NEXT: [[B:%.*]] = lshr i16 [[Z]], 4 ; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]] ; LEGAL16-NEXT: ret i16 [[R]] ; %z = zext i8 %x to i16 %b = lshr i16 %z, 4 %r = and i16 %b, %z ret i16 %r } define i16 @zext_ashr(i8 %x) { ; LEGAL8-LABEL: @zext_ashr( ; LEGAL8-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 2 ; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] ; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 ; LEGAL8-NEXT: ret i16 [[R]] ; ; LEGAL16-LABEL: @zext_ashr( ; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 ; LEGAL16-NEXT: [[TMP1:%.*]] = lshr i16 [[Z]], 2 ; LEGAL16-NEXT: [[R:%.*]] = and i16 [[TMP1]], [[Z]] ; LEGAL16-NEXT: ret i16 [[R]] ; %z = zext i8 %x to i16 %b = ashr i16 %z, 2 %r = and i16 %b, %z ret i16 %r } define i16 @zext_shl(i8 %x) { ; LEGAL8-LABEL: @zext_shl( ; LEGAL8-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 3 ; LEGAL8-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]] ; LEGAL8-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16 ; LEGAL8-NEXT: ret i16 [[R]] ; ; LEGAL16-LABEL: @zext_shl( ; LEGAL16-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 ; LEGAL16-NEXT: [[B:%.*]] = shl nuw nsw i16 [[Z]], 3 ; LEGAL16-NEXT: [[R:%.*]] = and i16 [[B]], [[Z]] ; LEGAL16-NEXT: ret i16 [[R]] ; %z = zext i8 %x to i16 %b = shl i16 %z, 3 %r = and i16 %b, %z ret i16 %r } define <2 x i16> @zext_add_vec(<2 x i8> %x) { ; ALL-LABEL: @zext_add_vec( ; ALL-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], ; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] ; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = add <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r } define <2 x i16> @zext_sub_vec(<2 x i8> %x) { ; ALL-LABEL: @zext_sub_vec( ; ALL-NEXT: [[TMP1:%.*]] = sub <2 x i8> , [[X:%.*]] ; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] ; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = sub <2 x i16> , %z %r = and <2 x i16> %b, %z ret <2 x i16> %r } define <2 x i16> @zext_mul_vec(<2 x i8> %x) { ; ALL-LABEL: @zext_mul_vec( ; ALL-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X:%.*]], ; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] ; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = mul <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r } define <2 x i16> @zext_lshr_vec(<2 x i8> %x) { ; ALL-LABEL: @zext_lshr_vec( ; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], ; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] ; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = lshr <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r } define <2 x i16> @zext_ashr_vec(<2 x i8> %x) { ; ALL-LABEL: @zext_ashr_vec( ; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], ; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] ; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = ashr <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r } define <2 x i16> @zext_shl_vec(<2 x i8> %x) { ; ALL-LABEL: @zext_shl_vec( ; ALL-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], ; ALL-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]] ; ALL-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16> ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = shl <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r } ; Don't create poison by narrowing a shift below the shift amount. define <2 x i16> @zext_lshr_vec_overshift(<2 x i8> %x) { ; ALL-LABEL: @zext_lshr_vec_overshift( ; ALL-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> ; ALL-NEXT: [[B:%.*]] = lshr <2 x i16> [[Z]], ; ALL-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]] ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = lshr <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r } ; Don't create poison by narrowing a shift below the shift amount. define <2 x i16> @zext_shl_vec_overshift(<2 x i8> %x) { ; ALL-LABEL: @zext_shl_vec_overshift( ; ALL-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16> ; ALL-NEXT: [[B:%.*]] = shl <2 x i16> [[Z]], ; ALL-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]] ; ALL-NEXT: ret <2 x i16> [[R]] ; %z = zext <2 x i8> %x to <2 x i16> %b = shl <2 x i16> %z, %r = and <2 x i16> %b, %z ret <2 x i16> %r }