307 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4define i32 @or_and_shifts1(i32 %x) {5; CHECK-LABEL: @or_and_shifts1(6; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 37; CHECK-NEXT: [[I1:%.*]] = and i32 [[I]], 88; CHECK-NEXT: [[I2:%.*]] = shl i32 [[X]], 59; CHECK-NEXT: [[I3:%.*]] = and i32 [[I2]], 3210; CHECK-NEXT: [[I4:%.*]] = or disjoint i32 [[I1]], [[I3]]11; CHECK-NEXT: ret i32 [[I4]]12;13 %i = shl i32 %x, 314 %i1 = and i32 %i, 1515 %i2 = shl i32 %x, 516 %i3 = and i32 %i2, 6017 %i4 = or i32 %i1, %i318 ret i32 %i419}20 21define i32 @or_and_shifts2(i32 %x) {22; CHECK-LABEL: @or_and_shifts2(23; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 324; CHECK-NEXT: [[I1:%.*]] = and i32 [[I]], 89625; CHECK-NEXT: [[I2:%.*]] = lshr i32 [[X]], 426; CHECK-NEXT: [[I3:%.*]] = and i32 [[I2]], 727; CHECK-NEXT: [[I4:%.*]] = or disjoint i32 [[I1]], [[I3]]28; CHECK-NEXT: ret i32 [[I4]]29;30 %i = shl i32 %x, 331 %i1 = and i32 %i, 89632 %i2 = lshr i32 %x, 433 %i3 = and i32 %i2, 734 %i4 = or i32 %i1, %i335 ret i32 %i436}37 38define i32 @or_and_shift_shift_and(i32 %x) {39; CHECK-LABEL: @or_and_shift_shift_and(40; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 341; CHECK-NEXT: [[I1:%.*]] = and i32 [[I]], 5642; CHECK-NEXT: [[I2:%.*]] = shl i32 [[X]], 243; CHECK-NEXT: [[I3:%.*]] = and i32 [[I2]], 2844; CHECK-NEXT: [[I4:%.*]] = or i32 [[I1]], [[I3]]45; CHECK-NEXT: ret i32 [[I4]]46;47 %i = and i32 %x, 748 %i1 = shl i32 %i, 349 %i2 = shl i32 %x, 250 %i3 = and i32 %i2, 2851 %i4 = or i32 %i1, %i352 ret i32 %i453}54 55define i32 @multiuse1(i32 %x) {56; CHECK-LABEL: @multiuse1(57; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X:%.*]], 158; CHECK-NEXT: [[I3:%.*]] = and i32 [[I]], 159; CHECK-NEXT: [[I1:%.*]] = lshr i32 [[X]], 160; CHECK-NEXT: [[I5:%.*]] = and i32 [[I1]], 261; CHECK-NEXT: [[I21:%.*]] = shl i32 [[X]], 662; CHECK-NEXT: [[I6:%.*]] = and i32 [[I21]], 38463; CHECK-NEXT: [[I7:%.*]] = or disjoint i32 [[I3]], [[I5]]64; CHECK-NEXT: [[I8:%.*]] = or disjoint i32 [[I7]], [[I6]]65; CHECK-NEXT: ret i32 [[I8]]66;67 %i = and i32 %x, 268 %i1 = and i32 %x, 469 %i2 = shl nuw nsw i32 %i, 670 %i3 = lshr exact i32 %i, 171 %i4 = shl nuw nsw i32 %i1, 672 %i5 = lshr exact i32 %i1, 173 %i6 = or i32 %i2, %i474 %i7 = or i32 %i3, %i575 %i8 = or i32 %i7, %i676 ret i32 %i877}78 79define i32 @multiuse2(i32 %x) {80; CHECK-LABEL: @multiuse2(81; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 182; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 1283; CHECK-NEXT: [[I3:%.*]] = shl i32 [[X]], 184; CHECK-NEXT: [[I5:%.*]] = and i32 [[I3]], 4885; CHECK-NEXT: [[I6:%.*]] = shl i32 [[X]], 186; CHECK-NEXT: [[I8:%.*]] = and i32 [[I6]], 19287; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 888; CHECK-NEXT: [[I10:%.*]] = and i32 [[TMP1]], 3225689; CHECK-NEXT: [[I11:%.*]] = or disjoint i32 [[I8]], [[I5]]90; CHECK-NEXT: [[I12:%.*]] = or disjoint i32 [[I2]], [[I11]]91; CHECK-NEXT: [[I13:%.*]] = or disjoint i32 [[I10]], [[I12]]92; CHECK-NEXT: ret i32 [[I13]]93;94 %i = and i32 %x, 695 %i1 = shl nuw nsw i32 %i, 896 %i2 = shl nuw nsw i32 %i, 197 %i3 = and i32 %x, 2498 %i4 = shl nuw nsw i32 %i3, 899 %i5 = shl nuw nsw i32 %i3, 1100 %i6 = and i32 %x, 96101 %i7 = shl nuw nsw i32 %i6, 8102 %i8 = shl nuw nsw i32 %i6, 1103 %i9 = or i32 %i1, %i4104 %i10 = or i32 %i7, %i9105 %i11 = or i32 %i8, %i5106 %i12 = or i32 %i2, %i11107 %i13 = or i32 %i10, %i12108 ret i32 %i13109}110 111define i32 @multiuse3(i32 %x) {112; CHECK-LABEL: @multiuse3(113; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X:%.*]], 1114; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 48115; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 6116; CHECK-NEXT: [[I5:%.*]] = and i32 [[TMP1]], 8064117; CHECK-NEXT: [[I6:%.*]] = lshr i32 [[X]], 1118; CHECK-NEXT: [[I7:%.*]] = and i32 [[I6]], 15119; CHECK-NEXT: [[I8:%.*]] = or disjoint i32 [[I2]], [[I7]]120; CHECK-NEXT: [[I9:%.*]] = or disjoint i32 [[I8]], [[I5]]121; CHECK-NEXT: ret i32 [[I9]]122;123 %i = and i32 %x, 96124 %i1 = shl nuw nsw i32 %i, 6125 %i2 = lshr exact i32 %i, 1126 %i3 = shl i32 %x, 6127 %i4 = and i32 %i3, 1920128 %i5 = or i32 %i1, %i4129 %i6 = lshr i32 %x, 1130 %i7 = and i32 %i6, 15131 %i8 = or i32 %i2, %i7132 %i9 = or i32 %i8, %i5133 ret i32 %i9134}135 136define i32 @multiuse4(i32 %x) local_unnamed_addr {137; CHECK-LABEL: @multiuse4(138; CHECK-NEXT: [[I1:%.*]] = icmp sgt i32 [[X:%.*]], -1139; CHECK-NEXT: br i1 [[I1]], label [[IF:%.*]], label [[ELSE:%.*]]140; CHECK: if:141; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X]], 22142; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 24143; CHECK-NEXT: [[I3:%.*]] = lshr i32 [[X]], 22144; CHECK-NEXT: [[I4:%.*]] = and i32 [[I3]], 480145; CHECK-NEXT: [[I5:%.*]] = or disjoint i32 [[I4]], [[I2]]146; CHECK-NEXT: br label [[END:%.*]]147; CHECK: else:148; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X]], 17149; CHECK-NEXT: [[I9:%.*]] = and i32 [[TMP1]], 16128150; CHECK-NEXT: br label [[END]]151; CHECK: end:152; CHECK-NEXT: [[I10:%.*]] = phi i32 [ [[I5]], [[IF]] ], [ [[I9]], [[ELSE]] ]153; CHECK-NEXT: ret i32 [[I10]]154;155 %i = and i32 %x, 100663296156 %i1 = icmp sgt i32 %x, -1157 br i1 %i1, label %if, label %else158 159if:160 %i2 = lshr exact i32 %i, 22161 %i3 = lshr i32 %x, 22162 %i4 = and i32 %i3, 480163 %i5 = or i32 %i4, %i2164 br label %end165 166else:167 %i6 = lshr exact i32 %i, 17168 %i7 = lshr i32 %x, 17169 %i8 = and i32 %i7, 15360170 %i9 = or i32 %i8, %i6171 br label %end172 173end:174 %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]175 ret i32 %i10176}177 178define i32 @multiuse5(i32 %x) local_unnamed_addr {179; CHECK-LABEL: @multiuse5(180; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 5181; CHECK-NEXT: [[I1:%.*]] = icmp sgt i32 [[X]], -1182; CHECK-NEXT: br i1 [[I1]], label [[IF:%.*]], label [[ELSE:%.*]]183; CHECK: if:184; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 21760185; CHECK-NEXT: [[I3:%.*]] = shl i32 [[X]], 5186; CHECK-NEXT: [[I4:%.*]] = and i32 [[I3]], 43520187; CHECK-NEXT: [[I5:%.*]] = or disjoint i32 [[I4]], [[I2]]188; CHECK-NEXT: br label [[END:%.*]]189; CHECK: else:190; CHECK-NEXT: [[I6:%.*]] = and i32 [[I]], 5570560191; CHECK-NEXT: [[I7:%.*]] = shl i32 [[X]], 5192; CHECK-NEXT: [[I8:%.*]] = and i32 [[I7]], 11141120193; CHECK-NEXT: [[I9:%.*]] = or disjoint i32 [[I8]], [[I6]]194; CHECK-NEXT: br label [[END]]195; CHECK: end:196; CHECK-NEXT: [[I10:%.*]] = phi i32 [ [[I5]], [[IF]] ], [ [[I9]], [[ELSE]] ]197; CHECK-NEXT: ret i32 [[I10]]198;199 %i = shl i32 %x, 5200 %i1 = icmp sgt i32 %x, -1201 br i1 %i1, label %if, label %else202 203if:204 %i2 = and i32 %i, 21760205 %i3 = and i32 %x, 1360206 %i4 = shl nuw nsw i32 %i3, 5207 %i5 = or i32 %i4, %i2208 br label %end209 210else:211 %i6 = and i32 %i, 5570560212 %i7 = and i32 %x, 348160213 %i8 = shl nuw nsw i32 %i7, 5214 %i9 = or i32 %i8, %i6215 br label %end216 217end:218 %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]219 ret i32 %i10220}221 222define i32 @shl_mask(i32 %x) {223; CHECK-LABEL: @shl_mask(224; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255225; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8226; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[Z]], [[S]]227; CHECK-NEXT: ret i32 [[R]]228;229 %z = and i32 %x, 255230 %s = shl i32 %z, 8231 %r = or i32 %z, %s232 ret i32 %r233}234 235define i32 @shl_mask_wrong_shl_const(i32 %x) {236; CHECK-LABEL: @shl_mask_wrong_shl_const(237; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255238; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 7239; CHECK-NEXT: [[R:%.*]] = or i32 [[Z]], [[S]]240; CHECK-NEXT: ret i32 [[R]]241;242 %z = and i32 %x, 255243 %s = shl i32 %z, 7244 %r = or i32 %z, %s245 ret i32 %r246}247 248define i37 @shl_mask_weird_type(i37 %x) {249; CHECK-LABEL: @shl_mask_weird_type(250; CHECK-NEXT: [[Z:%.*]] = and i37 [[X:%.*]], 255251; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i37 [[Z]], 8252; CHECK-NEXT: [[R:%.*]] = or disjoint i37 [[Z]], [[S]]253; CHECK-NEXT: ret i37 [[R]]254;255 %z = and i37 %x, 255256 %s = shl i37 %z, 8257 %r = or i37 %z, %s258 ret i37 %r259}260 261define i32 @shl_mask_extra_use(i32 %x, ptr %p) {262; CHECK-LABEL: @shl_mask_extra_use(263; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255264; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8265; CHECK-NEXT: store i32 [[S]], ptr [[P:%.*]], align 4266; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[Z]], [[S]]267; CHECK-NEXT: ret i32 [[R]]268;269 %z = and i32 %x, 255270 %s = shl i32 %z, 8271 store i32 %s, ptr %p, align 4272 %r = or i32 %z, %s273 ret i32 %r274}275 276; This could be "Z * 65793".277 278define i32 @shl_mul_mask(i32 %x) {279; CHECK-LABEL: @shl_mul_mask(280; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255281; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Z]], 65537282; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8283; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[S]]284; CHECK-NEXT: ret i32 [[R]]285;286 %z = and i32 %x, 255287 %m = mul i32 %z, 65537288 %s = shl i32 %z, 8289 %r = or i32 %m, %s290 ret i32 %r291}292 293define i32 @shl_mul_mask_wrong_mul_const(i32 %x) {294; CHECK-LABEL: @shl_mul_mask_wrong_mul_const(295; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255296; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Z]], 65535297; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8298; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[S]]299; CHECK-NEXT: ret i32 [[R]]300;301 %z = and i32 %x, 255302 %m = mul i32 %z, 65535303 %s = shl i32 %z, 8304 %r = or i32 %m, %s305 ret i32 %r306}307