forked from OSchip/llvm-project
[InstCombine] Allow common type conversions to i8/i16/i32
This, in instcombine, allows conversions to i8/i16/i32 (very common cases) even if the resulting type is not legal according to the data layout. This can often open up extra combine opportunities. Differential Revision: https://reviews.llvm.org/D42424 llvm-svn: 324174
This commit is contained in:
parent
891af03a55
commit
7174023f57
|
@ -144,12 +144,20 @@ Value *InstCombiner::EmitGEPOffset(User *GEP) {
|
|||
/// We don't want to convert from a legal to an illegal type or from a smaller
|
||||
/// to a larger illegal type. A width of '1' is always treated as a legal type
|
||||
/// because i1 is a fundamental type in IR, and there are many specialized
|
||||
/// optimizations for i1 types.
|
||||
/// optimizations for i1 types. Widths of 8, 16 or 32 are equally treated as
|
||||
/// legal to convert to, in order to open up more combining opportunities.
|
||||
/// NOTE: this treats i8, i16 and i32 specially, due to them being so common
|
||||
/// from frontend languages.
|
||||
bool InstCombiner::shouldChangeType(unsigned FromWidth,
|
||||
unsigned ToWidth) const {
|
||||
bool FromLegal = FromWidth == 1 || DL.isLegalInteger(FromWidth);
|
||||
bool ToLegal = ToWidth == 1 || DL.isLegalInteger(ToWidth);
|
||||
|
||||
// Convert to widths of 8, 16 or 32 even if they are not legal types. Only
|
||||
// shrink types, to prevent infinite loops.
|
||||
if (ToWidth < FromWidth && (ToWidth == 8 || ToWidth == 16 || ToWidth == 32))
|
||||
return true;
|
||||
|
||||
// If this is a legal integer from type, and the result would be an illegal
|
||||
// type, don't do the transformation.
|
||||
if (FromLegal && !ToLegal)
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
; 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
|
||||
; RUN: opt < %s -instcombine -data-layout="n8:16:32" -S | FileCheck %s
|
||||
; RUN: opt < %s -instcombine -data-layout="n16" -S | FileCheck %s
|
||||
|
||||
; 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]]
|
||||
; CHECK-LABEL: @zext_add(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 44
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%z = zext i8 %x to i16
|
||||
%b = add i16 %z, 44
|
||||
|
@ -24,17 +18,11 @@ define i16 @zext_add(i8 %x) {
|
|||
}
|
||||
|
||||
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]]
|
||||
; CHECK-LABEL: @zext_sub(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i8 -5, [[X:%.*]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%z = zext i8 %x to i16
|
||||
%b = sub i16 -5, %z
|
||||
|
@ -43,17 +31,11 @@ define i16 @zext_sub(i8 %x) {
|
|||
}
|
||||
|
||||
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]]
|
||||
; CHECK-LABEL: @zext_mul(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[X:%.*]], 3
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%z = zext i8 %x to i16
|
||||
%b = mul i16 %z, 3
|
||||
|
@ -62,17 +44,11 @@ define i16 @zext_mul(i8 %x) {
|
|||
}
|
||||
|
||||
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]]
|
||||
; CHECK-LABEL: @zext_lshr(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 4
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%z = zext i8 %x to i16
|
||||
%b = lshr i16 %z, 4
|
||||
|
@ -81,17 +57,11 @@ define i16 @zext_lshr(i8 %x) {
|
|||
}
|
||||
|
||||
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]]
|
||||
; CHECK-LABEL: @zext_ashr(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[X:%.*]], 2
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%z = zext i8 %x to i16
|
||||
%b = ashr i16 %z, 2
|
||||
|
@ -100,17 +70,11 @@ define i16 @zext_ashr(i8 %x) {
|
|||
}
|
||||
|
||||
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]]
|
||||
; CHECK-LABEL: @zext_shl(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 3
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2]] to i16
|
||||
; CHECK-NEXT: ret i16 [[R]]
|
||||
;
|
||||
%z = zext i8 %x to i16
|
||||
%b = shl i16 %z, 3
|
||||
|
@ -119,11 +83,11 @@ define i16 @zext_shl(i8 %x) {
|
|||
}
|
||||
|
||||
define <2 x i16> @zext_add_vec(<2 x i8> %x) {
|
||||
; ALL-LABEL: @zext_add_vec(
|
||||
; ALL-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 44, i8 42>
|
||||
; 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]]
|
||||
; CHECK-LABEL: @zext_add_vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X:%.*]], <i8 44, i8 42>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = add <2 x i16> %z, <i16 44, i16 42>
|
||||
|
@ -132,11 +96,11 @@ define <2 x i16> @zext_add_vec(<2 x i8> %x) {
|
|||
}
|
||||
|
||||
define <2 x i16> @zext_sub_vec(<2 x i8> %x) {
|
||||
; ALL-LABEL: @zext_sub_vec(
|
||||
; ALL-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -5, i8 -4>, [[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]]
|
||||
; CHECK-LABEL: @zext_sub_vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i8> <i8 -5, i8 -4>, [[X:%.*]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = sub <2 x i16> <i16 -5, i16 -4>, %z
|
||||
|
@ -145,11 +109,11 @@ define <2 x i16> @zext_sub_vec(<2 x i8> %x) {
|
|||
}
|
||||
|
||||
define <2 x i16> @zext_mul_vec(<2 x i8> %x) {
|
||||
; ALL-LABEL: @zext_mul_vec(
|
||||
; ALL-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 -2>
|
||||
; 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]]
|
||||
; CHECK-LABEL: @zext_mul_vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[X:%.*]], <i8 3, i8 -2>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = mul <2 x i16> %z, <i16 3, i16 -2>
|
||||
|
@ -158,11 +122,11 @@ define <2 x i16> @zext_mul_vec(<2 x i8> %x) {
|
|||
}
|
||||
|
||||
define <2 x i16> @zext_lshr_vec(<2 x i8> %x) {
|
||||
; ALL-LABEL: @zext_lshr_vec(
|
||||
; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 2>
|
||||
; 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]]
|
||||
; CHECK-LABEL: @zext_lshr_vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 4, i8 2>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = lshr <2 x i16> %z, <i16 4, i16 2>
|
||||
|
@ -171,11 +135,11 @@ define <2 x i16> @zext_lshr_vec(<2 x i8> %x) {
|
|||
}
|
||||
|
||||
define <2 x i16> @zext_ashr_vec(<2 x i8> %x) {
|
||||
; ALL-LABEL: @zext_ashr_vec(
|
||||
; ALL-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 2, i8 3>
|
||||
; 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]]
|
||||
; CHECK-LABEL: @zext_ashr_vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i8> [[X:%.*]], <i8 2, i8 3>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = ashr <2 x i16> %z, <i16 2, i16 3>
|
||||
|
@ -184,11 +148,11 @@ define <2 x i16> @zext_ashr_vec(<2 x i8> %x) {
|
|||
}
|
||||
|
||||
define <2 x i16> @zext_shl_vec(<2 x i8> %x) {
|
||||
; ALL-LABEL: @zext_shl_vec(
|
||||
; ALL-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 2>
|
||||
; 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]]
|
||||
; CHECK-LABEL: @zext_shl_vec(
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 2>
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i8> [[TMP1]], [[X]]
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = shl <2 x i16> %z, <i16 3, i16 2>
|
||||
|
@ -199,11 +163,11 @@ define <2 x i16> @zext_shl_vec(<2 x i8> %x) {
|
|||
; 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]], <i16 4, i16 8>
|
||||
; ALL-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
|
||||
; ALL-NEXT: ret <2 x i16> [[R]]
|
||||
; CHECK-LABEL: @zext_lshr_vec_overshift(
|
||||
; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
|
||||
; CHECK-NEXT: [[B:%.*]] = lshr <2 x i16> [[Z]], <i16 4, i16 8>
|
||||
; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = lshr <2 x i16> %z, <i16 4, i16 8>
|
||||
|
@ -214,11 +178,11 @@ define <2 x i16> @zext_lshr_vec_overshift(<2 x i8> %x) {
|
|||
; 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]], <i16 8, i16 2>
|
||||
; ALL-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
|
||||
; ALL-NEXT: ret <2 x i16> [[R]]
|
||||
; CHECK-LABEL: @zext_shl_vec_overshift(
|
||||
; CHECK-NEXT: [[Z:%.*]] = zext <2 x i8> [[X:%.*]] to <2 x i16>
|
||||
; CHECK-NEXT: [[B:%.*]] = shl <2 x i16> [[Z]], <i16 8, i16 2>
|
||||
; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[B]], [[Z]]
|
||||
; CHECK-NEXT: ret <2 x i16> [[R]]
|
||||
;
|
||||
%z = zext <2 x i8> %x to <2 x i16>
|
||||
%b = shl <2 x i16> %z, <i16 8, i16 2>
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -instcombine -S -debug 2>&1 | FileCheck %s
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
|
||||
; We are really checking that this doesn't loop forever. We would never
|
||||
; actually get to the checks here if it did.
|
||||
|
||||
define void @timeout(i16* nocapture readonly %cinfo) {
|
||||
; CHECK-LABEL: @timeout(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
||||
; CHECK: for.body:
|
||||
; CHECK-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i16, i16* [[CINFO:%.*]], i32 2
|
||||
; CHECK-NEXT: [[L:%.*]] = load i16, i16* [[ARRAYIDX15]], align 2
|
||||
; CHECK-NEXT: [[CMP17:%.*]] = icmp eq i16 [[L]], 0
|
||||
; CHECK-NEXT: [[EXTRACT_T1:%.*]] = trunc i16 [[L]] to i8
|
||||
; CHECK-NEXT: br i1 [[CMP17]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: [[DOTPRE:%.*]] = load i16, i16* [[ARRAYIDX15]], align 2
|
||||
; CHECK-NEXT: [[EXTRACT_T:%.*]] = trunc i16 [[DOTPRE]] to i8
|
||||
; CHECK-NEXT: br label [[IF_END]]
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: [[P_OFF0:%.*]] = phi i8 [ [[EXTRACT_T]], [[IF_THEN]] ], [ [[EXTRACT_T1]], [[FOR_BODY]] ]
|
||||
; CHECK-NEXT: [[SUB:%.*]] = add i8 [[P_OFF0]], -1
|
||||
; CHECK-NEXT: store i8 [[SUB]], i8* undef, align 1
|
||||
; CHECK-NEXT: br label [[FOR_BODY]]
|
||||
;
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body:
|
||||
%arrayidx15 = getelementptr inbounds i16, i16* %cinfo, i32 2
|
||||
%l = load i16, i16* %arrayidx15, align 2
|
||||
%cmp17 = icmp eq i16 %l, 0
|
||||
br i1 %cmp17, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
%.pre = load i16, i16* %arrayidx15, align 2
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
%p = phi i16 [ %.pre, %if.then ], [ %l, %for.body ]
|
||||
%conv19 = trunc i16 %p to i8
|
||||
%sub = add i8 %conv19, -1
|
||||
store i8 %sub, i8* undef, align 1
|
||||
br label %for.body
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
target datalayout = "n64"
|
||||
|
||||
; Tests for removing zext/trunc from/to i8, i16 and i32, even if it is
|
||||
; not a legal type.
|
||||
|
||||
define i8 @test1(i8 %x, i8 %y) {
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: [[C:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i8 [[C]]
|
||||
;
|
||||
%xz = zext i8 %x to i64
|
||||
%yz = zext i8 %y to i64
|
||||
%c = add i64 %xz, %yz
|
||||
%d = trunc i64 %c to i8
|
||||
ret i8 %d
|
||||
}
|
||||
|
||||
define i16 @test2(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: [[C:%.*]] = add i16 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i16 [[C]]
|
||||
;
|
||||
%xz = zext i16 %x to i64
|
||||
%yz = zext i16 %y to i64
|
||||
%c = add i64 %xz, %yz
|
||||
%d = trunc i64 %c to i16
|
||||
ret i16 %d
|
||||
}
|
||||
|
||||
define i32 @test3(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test3(
|
||||
; CHECK-NEXT: [[C:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: ret i32 [[C]]
|
||||
;
|
||||
%xz = zext i32 %x to i64
|
||||
%yz = zext i32 %y to i64
|
||||
%c = add i64 %xz, %yz
|
||||
%d = trunc i64 %c to i32
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define i9 @test4(i9 %x, i9 %y) {
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK-NEXT: [[XZ:%.*]] = zext i9 [[X:%.*]] to i64
|
||||
; CHECK-NEXT: [[YZ:%.*]] = zext i9 [[Y:%.*]] to i64
|
||||
; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[XZ]], [[YZ]]
|
||||
; CHECK-NEXT: [[D:%.*]] = trunc i64 [[C]] to i9
|
||||
; CHECK-NEXT: ret i9 [[D]]
|
||||
;
|
||||
%xz = zext i9 %x to i64
|
||||
%yz = zext i9 %y to i64
|
||||
%c = add i64 %xz, %yz
|
||||
%d = trunc i64 %c to i9
|
||||
ret i9 %d
|
||||
}
|
Loading…
Reference in New Issue