236 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Iff we know that trunc only chops off the sign bits,5; and not all of them, then we can bypass said trunc6; for the purpose of sign extension.7 8declare void @use8(i8)9declare void @use4(i4)10declare void @usevec(<2 x i8>)11 12define i16 @t0(i8 %x) {13; CHECK-LABEL: @t0(14; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 515; CHECK-NEXT: call void @use8(i8 [[A]])16; CHECK-NEXT: [[C:%.*]] = sext i8 [[A]] to i1617; CHECK-NEXT: ret i16 [[C]]18;19 %a = ashr i8 %x, 520 call void @use8(i8 %a)21 %b = trunc i8 %a to i422 %c = sext i4 %b to i1623 ret i16 %c24}25 26define i16 @t1(i8 %x) {27; CHECK-LABEL: @t1(28; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 429; CHECK-NEXT: call void @use8(i8 [[A]])30; CHECK-NEXT: [[C:%.*]] = sext i8 [[A]] to i1631; CHECK-NEXT: ret i16 [[C]]32;33 %a = ashr i8 %x, 434 call void @use8(i8 %a)35 %b = trunc i8 %a to i436 %c = sext i4 %b to i1637 ret i16 %c38}39 40; Here we don't know that %a has any sign bits from %x left41define i16 @n2(i8 %x) {42; CHECK-LABEL: @n2(43; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 344; CHECK-NEXT: call void @use8(i8 [[A]])45; CHECK-NEXT: [[B:%.*]] = trunc i8 [[A]] to i446; CHECK-NEXT: [[C:%.*]] = sext i4 [[B]] to i1647; CHECK-NEXT: ret i16 [[C]]48;49 %a = ashr i8 %x, 350 call void @use8(i8 %a)51 %b = trunc i8 %a to i452 %c = sext i4 %b to i1653 ret i16 %c54}55 56define <2 x i16> @t3_vec(<2 x i8> %x) {57; CHECK-LABEL: @t3_vec(58; CHECK-NEXT: [[A:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 4)59; CHECK-NEXT: call void @usevec(<2 x i8> [[A]])60; CHECK-NEXT: [[C:%.*]] = sext <2 x i8> [[A]] to <2 x i16>61; CHECK-NEXT: ret <2 x i16> [[C]]62;63 %a = ashr <2 x i8> %x, <i8 4, i8 4>64 call void @usevec(<2 x i8> %a)65 %b = trunc <2 x i8> %a to <2 x i4>66 %c = sext <2 x i4> %b to <2 x i16>67 ret <2 x i16> %c68}69 70define <2 x i16> @t4_vec_nonsplat(<2 x i8> %x) {71; CHECK-LABEL: @t4_vec_nonsplat(72; CHECK-NEXT: [[A:%.*]] = ashr <2 x i8> [[X:%.*]], <i8 4, i8 3>73; CHECK-NEXT: call void @usevec(<2 x i8> [[A]])74; CHECK-NEXT: [[B:%.*]] = trunc <2 x i8> [[A]] to <2 x i4>75; CHECK-NEXT: [[C:%.*]] = sext <2 x i4> [[B]] to <2 x i16>76; CHECK-NEXT: ret <2 x i16> [[C]]77;78 %a = ashr <2 x i8> %x, <i8 4, i8 3>79 call void @usevec(<2 x i8> %a)80 %b = trunc <2 x i8> %a to <2 x i4>81 %c = sext <2 x i4> %b to <2 x i16>82 ret <2 x i16> %c83}84 85define i16 @t5_extrause(i8 %x) {86; CHECK-LABEL: @t5_extrause(87; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 588; CHECK-NEXT: call void @use8(i8 [[A]])89; CHECK-NEXT: [[B:%.*]] = trunc nsw i8 [[A]] to i490; CHECK-NEXT: call void @use4(i4 [[B]])91; CHECK-NEXT: [[C:%.*]] = sext i8 [[A]] to i1692; CHECK-NEXT: ret i16 [[C]]93;94 %a = ashr i8 %x, 595 call void @use8(i8 %a)96 %b = trunc i8 %a to i497 call void @use4(i4 %b)98 %c = sext i4 %b to i1699 ret i16 %c100}101 102define i64 @narrow_source_matching_signbits(i32 %x) {103; CHECK-LABEL: @narrow_source_matching_signbits(104; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 7105; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M]]106; CHECK-NEXT: [[C:%.*]] = sext i32 [[A]] to i64107; CHECK-NEXT: ret i64 [[C]]108;109 %m = and i32 %x, 7110 %a = shl nsw i32 -1, %m111 %b = trunc i32 %a to i8112 %c = sext i8 %b to i64113 ret i64 %c114}115 116; negative test - not enough sign-bits117 118define i64 @narrow_source_not_matching_signbits(i32 %x) {119; CHECK-LABEL: @narrow_source_not_matching_signbits(120; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 8121; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M]]122; CHECK-NEXT: [[B:%.*]] = trunc i32 [[A]] to i8123; CHECK-NEXT: [[C:%.*]] = sext i8 [[B]] to i64124; CHECK-NEXT: ret i64 [[C]]125;126 %m = and i32 %x, 8127 %a = shl nsw i32 -1, %m128 %b = trunc i32 %a to i8129 %c = sext i8 %b to i64130 ret i64 %c131}132 133define i24 @wide_source_matching_signbits(i32 %x) {134; CHECK-LABEL: @wide_source_matching_signbits(135; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 7136; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M]]137; CHECK-NEXT: [[C:%.*]] = trunc nsw i32 [[A]] to i24138; CHECK-NEXT: ret i24 [[C]]139;140 %m = and i32 %x, 7141 %a = shl nsw i32 -1, %m142 %b = trunc i32 %a to i8143 %c = sext i8 %b to i24144 ret i24 %c145}146 147define i32 @wide_source_matching_signbits_has_nsw_flag(i64 %i) {148; CHECK-LABEL: define i32 @wide_source_matching_signbits_has_nsw_flag(149; CHECK-SAME: i64 [[I:%.*]]) {150; CHECK-NEXT: [[A:%.*]] = trunc nsw i64 [[I]] to i32151; CHECK-NEXT: ret i32 [[A]]152;153 %a = trunc nsw i64 %i to i16154 %b = sext i16 %a to i32155 ret i32 %b156}157 158; negative test - not enough sign-bits159 160define i24 @wide_source_not_matching_signbits(i32 %x) {161; CHECK-LABEL: @wide_source_not_matching_signbits(162; CHECK-NEXT: [[M2:%.*]] = and i32 [[X:%.*]], 8163; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M2]]164; CHECK-NEXT: [[B:%.*]] = trunc i32 [[A]] to i8165; CHECK-NEXT: [[C:%.*]] = sext i8 [[B]] to i24166; CHECK-NEXT: ret i24 [[C]]167;168 %m2 = and i32 %x, 8169 %a = shl nsw i32 -1, %m2170 %b = trunc i32 %a to i8171 %c = sext i8 %b to i24172 ret i24 %c173}174 175define i32 @same_source_matching_signbits(i32 %x) {176; CHECK-LABEL: @same_source_matching_signbits(177; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 7178; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M]]179; CHECK-NEXT: ret i32 [[A]]180;181 %m = and i32 %x, 7182 %a = shl nsw i32 -1, %m183 %b = trunc i32 %a to i8184 %c = sext i8 %b to i32185 ret i32 %c186}187 188; negative test - not enough sign-bits189 190define i32 @same_source_not_matching_signbits(i32 %x) {191; CHECK-LABEL: @same_source_not_matching_signbits(192; CHECK-NEXT: [[M2:%.*]] = and i32 [[X:%.*]], 8193; CHECK-NEXT: [[TMP1:%.*]] = shl i32 -16777216, [[M2]]194; CHECK-NEXT: [[C:%.*]] = ashr exact i32 [[TMP1]], 24195; CHECK-NEXT: ret i32 [[C]]196;197 %m2 = and i32 %x, 8198 %a = shl nsw i32 -1, %m2199 %b = trunc i32 %a to i8200 %c = sext i8 %b to i32201 ret i32 %c202}203 204define i32 @same_source_matching_signbits_extra_use(i32 %x) {205; CHECK-LABEL: @same_source_matching_signbits_extra_use(206; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 7207; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M]]208; CHECK-NEXT: [[B:%.*]] = trunc nsw i32 [[A]] to i8209; CHECK-NEXT: call void @use8(i8 [[B]])210; CHECK-NEXT: ret i32 [[A]]211;212 %m = and i32 %x, 7213 %a = shl nsw i32 -1, %m214 %b = trunc i32 %a to i8215 call void @use8(i8 %b)216 %c = sext i8 %b to i32217 ret i32 %c218}219 220define i32 @same_source_not_matching_signbits_extra_use(i32 %x) {221; CHECK-LABEL: @same_source_not_matching_signbits_extra_use(222; CHECK-NEXT: [[M2:%.*]] = and i32 [[X:%.*]], 8223; CHECK-NEXT: [[A:%.*]] = shl nsw i32 -1, [[M2]]224; CHECK-NEXT: [[B:%.*]] = trunc i32 [[A]] to i8225; CHECK-NEXT: call void @use8(i8 [[B]])226; CHECK-NEXT: [[C:%.*]] = sext i8 [[B]] to i32227; CHECK-NEXT: ret i32 [[C]]228;229 %m2 = and i32 %x, 8230 %a = shl nsw i32 -1, %m2231 %b = trunc i32 %a to i8232 call void @use8(i8 %b)233 %c = sext i8 %b to i32234 ret i32 %c235}236