169 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use6(i6)5declare void @use8(i8)6 7define i6 @trunc_lshr(i8 %x) {8; CHECK-LABEL: @trunc_lshr(9; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i610; CHECK-NEXT: [[TMP2:%.*]] = lshr i6 [[TMP1]], 211; CHECK-NEXT: [[R:%.*]] = and i6 [[TMP2]], 1412; CHECK-NEXT: ret i6 [[R]]13;14 %s = lshr i8 %x, 215 %t = trunc i8 %s to i616 %r = and i6 %t, 1417 ret i6 %r18}19 20; The 'and' is eliminated.21 22define i6 @trunc_lshr_exact_mask(i8 %x) {23; CHECK-LABEL: @trunc_lshr_exact_mask(24; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i625; CHECK-NEXT: [[TMP2:%.*]] = lshr i6 [[TMP1]], 226; CHECK-NEXT: ret i6 [[TMP2]]27;28 %s = lshr i8 %x, 229 %t = trunc i8 %s to i630 %r = and i6 %t, 1531 ret i6 %r32}33 34; negative test - a high bit of x is in the result35 36define i6 @trunc_lshr_big_mask(i8 %x) {37; CHECK-LABEL: @trunc_lshr_big_mask(38; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 239; CHECK-NEXT: [[T:%.*]] = trunc nuw i8 [[S]] to i640; CHECK-NEXT: [[R:%.*]] = and i6 [[T]], 3141; CHECK-NEXT: ret i6 [[R]]42;43 %s = lshr i8 %x, 244 %t = trunc i8 %s to i645 %r = and i6 %t, 3146 ret i6 %r47}48 49; negative test - too many uses50 51define i6 @trunc_lshr_use1(i8 %x) {52; CHECK-LABEL: @trunc_lshr_use1(53; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 254; CHECK-NEXT: call void @use8(i8 [[S]])55; CHECK-NEXT: [[T:%.*]] = trunc nuw i8 [[S]] to i656; CHECK-NEXT: [[R:%.*]] = and i6 [[T]], 1557; CHECK-NEXT: ret i6 [[R]]58;59 %s = lshr i8 %x, 260 call void @use8(i8 %s)61 %t = trunc i8 %s to i662 %r = and i6 %t, 1563 ret i6 %r64}65 66; negative test - too many uses67 68define i6 @trunc_lshr_use2(i8 %x) {69; CHECK-LABEL: @trunc_lshr_use2(70; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 271; CHECK-NEXT: [[T:%.*]] = trunc nuw i8 [[S]] to i672; CHECK-NEXT: call void @use6(i6 [[T]])73; CHECK-NEXT: [[R:%.*]] = and i6 [[T]], 1574; CHECK-NEXT: ret i6 [[R]]75;76 %s = lshr i8 %x, 277 %t = trunc i8 %s to i678 call void @use6(i6 %t)79 %r = and i6 %t, 1580 ret i6 %r81}82 83; Splat vectors are ok.84 85define <2 x i7> @trunc_lshr_vec_splat(<2 x i16> %x) {86; CHECK-LABEL: @trunc_lshr_vec_splat(87; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i7>88; CHECK-NEXT: [[TMP2:%.*]] = lshr <2 x i7> [[TMP1]], splat (i7 5)89; CHECK-NEXT: [[R:%.*]] = and <2 x i7> [[TMP2]], splat (i7 1)90; CHECK-NEXT: ret <2 x i7> [[R]]91;92 %s = lshr <2 x i16> %x, <i16 5, i16 5>93 %t = trunc <2 x i16> %s to <2 x i7>94 %r = and <2 x i7> %t, <i7 1, i7 1>95 ret <2 x i7> %r96}97 98; The 'and' is eliminated.99 100define <2 x i7> @trunc_lshr_vec_splat_exact_mask(<2 x i16> %x) {101; CHECK-LABEL: @trunc_lshr_vec_splat_exact_mask(102; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i7>103; CHECK-NEXT: [[TMP2:%.*]] = lshr <2 x i7> [[TMP1]], splat (i7 6)104; CHECK-NEXT: ret <2 x i7> [[TMP2]]105;106 %s = lshr <2 x i16> %x, <i16 6, i16 6>107 %t = trunc <2 x i16> %s to <2 x i7>108 %r = and <2 x i7> %t, <i7 1, i7 1>109 ret <2 x i7> %r110}111 112; negative test - the shift is too big for the narrow type113 114define <2 x i7> @trunc_lshr_big_shift(<2 x i16> %x) {115; CHECK-LABEL: @trunc_lshr_big_shift(116; CHECK-NEXT: [[S:%.*]] = lshr <2 x i16> [[X:%.*]], splat (i16 7)117; CHECK-NEXT: [[T:%.*]] = trunc <2 x i16> [[S]] to <2 x i7>118; CHECK-NEXT: [[R:%.*]] = and <2 x i7> [[T]], splat (i7 1)119; CHECK-NEXT: ret <2 x i7> [[R]]120;121 %s = lshr <2 x i16> %x, <i16 7, i16 7>122 %t = trunc <2 x i16> %s to <2 x i7>123 %r = and <2 x i7> %t, <i7 1, i7 1>124 ret <2 x i7> %r125}126 127; High bits could also be set rather than cleared.128 129define i6 @or_trunc_lshr(i8 %x) {130; CHECK-LABEL: @or_trunc_lshr(131; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i6132; CHECK-NEXT: [[TMP2:%.*]] = lshr i6 [[TMP1]], 1133; CHECK-NEXT: [[R:%.*]] = or disjoint i6 [[TMP2]], -32134; CHECK-NEXT: ret i6 [[R]]135;136 %s = lshr i8 %x, 1137 %t = trunc i8 %s to i6138 %r = or i6 %t, 32 ; 0b100000139 ret i6 %r140}141 142define i6 @or_trunc_lshr_more(i8 %x) {143; CHECK-LABEL: @or_trunc_lshr_more(144; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i6145; CHECK-NEXT: [[TMP2:%.*]] = lshr i6 [[TMP1]], 4146; CHECK-NEXT: [[R:%.*]] = or disjoint i6 [[TMP2]], -4147; CHECK-NEXT: ret i6 [[R]]148;149 %s = lshr i8 %x, 4150 %t = trunc i8 %s to i6151 %r = or i6 %t, 60 ; 0b111100152 ret i6 %r153}154 155; negative test - need all high bits to be undemanded156 157define i6 @or_trunc_lshr_small_mask(i8 %x) {158; CHECK-LABEL: @or_trunc_lshr_small_mask(159; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 4160; CHECK-NEXT: [[T:%.*]] = trunc nuw nsw i8 [[S]] to i6161; CHECK-NEXT: [[R:%.*]] = or i6 [[T]], -8162; CHECK-NEXT: ret i6 [[R]]163;164 %s = lshr i8 %x, 4165 %t = trunc i8 %s to i6166 %r = or i6 %t, 56 ; 0b111000167 ret i6 %r168}169