197 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"4 5; Perform the shift first and merge the truncs as long as all zero/sign6; bits created by the shift are removed by the trunc.7 8declare void @use(i32)9 10define i8 @trunc_lshr_trunc(i64 %a) {11; CHECK-LABEL: @trunc_lshr_trunc(12; CHECK-NEXT: [[C1:%.*]] = lshr i64 [[A:%.*]], 813; CHECK-NEXT: [[D:%.*]] = trunc i64 [[C1]] to i814; CHECK-NEXT: ret i8 [[D]]15;16 %b = trunc i64 %a to i3217 %c = lshr i32 %b, 818 %d = trunc i32 %c to i819 ret i8 %d20}21 22define <2 x i8> @trunc_shl_trunc(<2 x i64> %a) {23; CHECK-LABEL: @trunc_shl_trunc(24; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>25; CHECK-NEXT: [[C:%.*]] = shl <2 x i32> [[B]], <i32 9, i32 7>26; CHECK-NEXT: [[D:%.*]] = trunc <2 x i32> [[C]] to <2 x i8>27; CHECK-NEXT: ret <2 x i8> [[D]]28;29 %b = trunc <2 x i64> %a to <2 x i32>30 %c = shl <2 x i32> %b, <i32 9, i32 7>31 %d = trunc <2 x i32> %c to <2 x i8>32 ret <2 x i8> %d33}34 35define <2 x i8> @trunc_lshr_trunc_uniform(<2 x i64> %a) {36; CHECK-LABEL: @trunc_lshr_trunc_uniform(37; CHECK-NEXT: [[C1:%.*]] = lshr <2 x i64> [[A:%.*]], splat (i64 8)38; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[C1]] to <2 x i8>39; CHECK-NEXT: ret <2 x i8> [[D]]40;41 %b = trunc <2 x i64> %a to <2 x i32>42 %c = lshr <2 x i32> %b, <i32 8, i32 8>43 %d = trunc <2 x i32> %c to <2 x i8>44 ret <2 x i8> %d45}46 47define <2 x i8> @trunc_lshr_trunc_nonuniform(<2 x i64> %a) {48; CHECK-LABEL: @trunc_lshr_trunc_nonuniform(49; CHECK-NEXT: [[C1:%.*]] = lshr <2 x i64> [[A:%.*]], <i64 8, i64 2>50; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[C1]] to <2 x i8>51; CHECK-NEXT: ret <2 x i8> [[D]]52;53 %b = trunc <2 x i64> %a to <2 x i32>54 %c = lshr <2 x i32> %b, <i32 8, i32 2>55 %d = trunc <2 x i32> %c to <2 x i8>56 ret <2 x i8> %d57}58 59define <2 x i8> @trunc_lshr_trunc_uniform_poison(<2 x i64> %a) {60; CHECK-LABEL: @trunc_lshr_trunc_uniform_poison(61; CHECK-NEXT: [[C1:%.*]] = lshr <2 x i64> [[A:%.*]], <i64 24, i64 poison>62; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[C1]] to <2 x i8>63; CHECK-NEXT: ret <2 x i8> [[D]]64;65 %b = trunc <2 x i64> %a to <2 x i32>66 %c = lshr <2 x i32> %b, <i32 24, i32 poison>67 %d = trunc <2 x i32> %c to <2 x i8>68 ret <2 x i8> %d69}70 71define i8 @trunc_lshr_trunc_outofrange(i64 %a) {72; CHECK-LABEL: @trunc_lshr_trunc_outofrange(73; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A:%.*]] to i3274; CHECK-NEXT: [[C:%.*]] = lshr i32 [[B]], 2575; CHECK-NEXT: [[D:%.*]] = trunc nuw nsw i32 [[C]] to i876; CHECK-NEXT: ret i8 [[D]]77;78 %b = trunc i64 %a to i3279 %c = lshr i32 %b, 2580 %d = trunc i32 %c to i881 ret i8 %d82}83 84define <2 x i8> @trunc_lshr_trunc_nonuniform_outofrange(<2 x i64> %a) {85; CHECK-LABEL: @trunc_lshr_trunc_nonuniform_outofrange(86; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>87; CHECK-NEXT: [[C:%.*]] = lshr <2 x i32> [[B]], <i32 8, i32 25>88; CHECK-NEXT: [[D:%.*]] = trunc <2 x i32> [[C]] to <2 x i8>89; CHECK-NEXT: ret <2 x i8> [[D]]90;91 %b = trunc <2 x i64> %a to <2 x i32>92 %c = lshr <2 x i32> %b, <i32 8, i32 25>93 %d = trunc <2 x i32> %c to <2 x i8>94 ret <2 x i8> %d95}96 97define i8 @trunc_ashr_trunc(i64 %a) {98; CHECK-LABEL: @trunc_ashr_trunc(99; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[A:%.*]], 8100; CHECK-NEXT: [[D:%.*]] = trunc i64 [[TMP1]] to i8101; CHECK-NEXT: ret i8 [[D]]102;103 %b = trunc i64 %a to i32104 %c = ashr i32 %b, 8105 %d = trunc i32 %c to i8106 ret i8 %d107}108 109define i8 @trunc_ashr_trunc_exact(i64 %a) {110; CHECK-LABEL: @trunc_ashr_trunc_exact(111; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i64 [[A:%.*]], 8112; CHECK-NEXT: [[D:%.*]] = trunc i64 [[TMP1]] to i8113; CHECK-NEXT: ret i8 [[D]]114;115 %b = trunc i64 %a to i32116 %c = ashr exact i32 %b, 8117 %d = trunc i32 %c to i8118 ret i8 %d119}120 121define <2 x i8> @trunc_ashr_trunc_uniform(<2 x i64> %a) {122; CHECK-LABEL: @trunc_ashr_trunc_uniform(123; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i64> [[A:%.*]], splat (i64 8)124; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i8>125; CHECK-NEXT: ret <2 x i8> [[D]]126;127 %b = trunc <2 x i64> %a to <2 x i32>128 %c = ashr <2 x i32> %b, <i32 8, i32 8>129 %d = trunc <2 x i32> %c to <2 x i8>130 ret <2 x i8> %d131}132 133define <2 x i8> @trunc_ashr_trunc_nonuniform(<2 x i64> %a) {134; CHECK-LABEL: @trunc_ashr_trunc_nonuniform(135; CHECK-NEXT: [[C1:%.*]] = ashr <2 x i64> [[A:%.*]], <i64 0, i64 23>136; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[C1]] to <2 x i8>137; CHECK-NEXT: ret <2 x i8> [[D]]138;139 %b = trunc <2 x i64> %a to <2 x i32>140 %c = ashr <2 x i32> %b, <i32 0, i32 23>141 %d = trunc <2 x i32> %c to <2 x i8>142 ret <2 x i8> %d143}144 145define <2 x i8> @trunc_ashr_trunc_uniform_poison(<2 x i64> %a) {146; CHECK-LABEL: @trunc_ashr_trunc_uniform_poison(147; CHECK-NEXT: [[C1:%.*]] = ashr <2 x i64> [[A:%.*]], <i64 8, i64 poison>148; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[C1]] to <2 x i8>149; CHECK-NEXT: ret <2 x i8> [[D]]150;151 %b = trunc <2 x i64> %a to <2 x i32>152 %c = ashr <2 x i32> %b, <i32 8, i32 poison>153 %d = trunc <2 x i32> %c to <2 x i8>154 ret <2 x i8> %d155}156 157define i8 @trunc_ashr_trunc_outofrange(i64 %a) {158; CHECK-LABEL: @trunc_ashr_trunc_outofrange(159; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A:%.*]] to i32160; CHECK-NEXT: [[C:%.*]] = ashr i32 [[B]], 25161; CHECK-NEXT: [[D:%.*]] = trunc nsw i32 [[C]] to i8162; CHECK-NEXT: ret i8 [[D]]163;164 %b = trunc i64 %a to i32165 %c = ashr i32 %b, 25166 %d = trunc i32 %c to i8167 ret i8 %d168}169 170define <2 x i8> @trunc_ashr_trunc_nonuniform_outofrange(<2 x i64> %a) {171; CHECK-LABEL: @trunc_ashr_trunc_nonuniform_outofrange(172; CHECK-NEXT: [[B:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i32>173; CHECK-NEXT: [[C:%.*]] = ashr <2 x i32> [[B]], <i32 8, i32 25>174; CHECK-NEXT: [[D:%.*]] = trunc <2 x i32> [[C]] to <2 x i8>175; CHECK-NEXT: ret <2 x i8> [[D]]176;177 %b = trunc <2 x i64> %a to <2 x i32>178 %c = ashr <2 x i32> %b, <i32 8, i32 25>179 %d = trunc <2 x i32> %c to <2 x i8>180 ret <2 x i8> %d181}182 183define i8 @trunc_ashr_trunc_multiuse(i64 %a) {184; CHECK-LABEL: @trunc_ashr_trunc_multiuse(185; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A:%.*]] to i32186; CHECK-NEXT: [[C:%.*]] = ashr i32 [[B]], 9187; CHECK-NEXT: [[D:%.*]] = trunc i32 [[C]] to i8188; CHECK-NEXT: call void @use(i32 [[C]])189; CHECK-NEXT: ret i8 [[D]]190;191 %b = trunc i64 %a to i32192 %c = ashr i32 %b, 9193 %d = trunc i32 %c to i8194 call void @use(i32 %c)195 ret i8 %d196}197