1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4define i32 @or_and_shifts1(i32 %x) { 5; CHECK-LABEL: @or_and_shifts1( 6; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 3 7; CHECK-NEXT: [[I1:%.*]] = and i32 [[I]], 8 8; CHECK-NEXT: [[I2:%.*]] = shl i32 [[X]], 5 9; CHECK-NEXT: [[I3:%.*]] = and i32 [[I2]], 32 10; CHECK-NEXT: [[I4:%.*]] = or disjoint i32 [[I1]], [[I3]] 11; CHECK-NEXT: ret i32 [[I4]] 12; 13 %i = shl i32 %x, 3 14 %i1 = and i32 %i, 15 15 %i2 = shl i32 %x, 5 16 %i3 = and i32 %i2, 60 17 %i4 = or i32 %i1, %i3 18 ret i32 %i4 19} 20 21define i32 @or_and_shifts2(i32 %x) { 22; CHECK-LABEL: @or_and_shifts2( 23; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 3 24; CHECK-NEXT: [[I1:%.*]] = and i32 [[I]], 896 25; CHECK-NEXT: [[I2:%.*]] = lshr i32 [[X]], 4 26; CHECK-NEXT: [[I3:%.*]] = and i32 [[I2]], 7 27; CHECK-NEXT: [[I4:%.*]] = or disjoint i32 [[I1]], [[I3]] 28; CHECK-NEXT: ret i32 [[I4]] 29; 30 %i = shl i32 %x, 3 31 %i1 = and i32 %i, 896 32 %i2 = lshr i32 %x, 4 33 %i3 = and i32 %i2, 7 34 %i4 = or i32 %i1, %i3 35 ret i32 %i4 36} 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:%.*]], 3 41; CHECK-NEXT: [[I1:%.*]] = and i32 [[I]], 56 42; CHECK-NEXT: [[I2:%.*]] = shl i32 [[X]], 2 43; CHECK-NEXT: [[I3:%.*]] = and i32 [[I2]], 28 44; CHECK-NEXT: [[I4:%.*]] = or i32 [[I1]], [[I3]] 45; CHECK-NEXT: ret i32 [[I4]] 46; 47 %i = and i32 %x, 7 48 %i1 = shl i32 %i, 3 49 %i2 = shl i32 %x, 2 50 %i3 = and i32 %i2, 28 51 %i4 = or i32 %i1, %i3 52 ret i32 %i4 53} 54 55define i32 @multiuse1(i32 %x) { 56; CHECK-LABEL: @multiuse1( 57; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X:%.*]], 1 58; CHECK-NEXT: [[I3:%.*]] = and i32 [[I]], 1 59; CHECK-NEXT: [[I1:%.*]] = lshr i32 [[X]], 1 60; CHECK-NEXT: [[I5:%.*]] = and i32 [[I1]], 2 61; CHECK-NEXT: [[I21:%.*]] = shl i32 [[X]], 6 62; CHECK-NEXT: [[I6:%.*]] = and i32 [[I21]], 384 63; 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, 2 68 %i1 = and i32 %x, 4 69 %i2 = shl nuw nsw i32 %i, 6 70 %i3 = lshr exact i32 %i, 1 71 %i4 = shl nuw nsw i32 %i1, 6 72 %i5 = lshr exact i32 %i1, 1 73 %i6 = or i32 %i2, %i4 74 %i7 = or i32 %i3, %i5 75 %i8 = or i32 %i7, %i6 76 ret i32 %i8 77} 78 79define i32 @multiuse2(i32 %x) { 80; CHECK-LABEL: @multiuse2( 81; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 1 82; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 12 83; CHECK-NEXT: [[I3:%.*]] = shl i32 [[X]], 1 84; CHECK-NEXT: [[I5:%.*]] = and i32 [[I3]], 48 85; CHECK-NEXT: [[I6:%.*]] = shl i32 [[X]], 1 86; CHECK-NEXT: [[I8:%.*]] = and i32 [[I6]], 192 87; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 8 88; CHECK-NEXT: [[I10:%.*]] = and i32 [[TMP1]], 32256 89; 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, 6 95 %i1 = shl nuw nsw i32 %i, 8 96 %i2 = shl nuw nsw i32 %i, 1 97 %i3 = and i32 %x, 24 98 %i4 = shl nuw nsw i32 %i3, 8 99 %i5 = shl nuw nsw i32 %i3, 1 100 %i6 = and i32 %x, 96 101 %i7 = shl nuw nsw i32 %i6, 8 102 %i8 = shl nuw nsw i32 %i6, 1 103 %i9 = or i32 %i1, %i4 104 %i10 = or i32 %i7, %i9 105 %i11 = or i32 %i8, %i5 106 %i12 = or i32 %i2, %i11 107 %i13 = or i32 %i10, %i12 108 ret i32 %i13 109} 110 111define i32 @multiuse3(i32 %x) { 112; CHECK-LABEL: @multiuse3( 113; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X:%.*]], 1 114; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 48 115; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 6 116; CHECK-NEXT: [[I5:%.*]] = and i32 [[TMP1]], 8064 117; CHECK-NEXT: [[I6:%.*]] = lshr i32 [[X]], 1 118; CHECK-NEXT: [[I7:%.*]] = and i32 [[I6]], 15 119; 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, 96 124 %i1 = shl nuw nsw i32 %i, 6 125 %i2 = lshr exact i32 %i, 1 126 %i3 = shl i32 %x, 6 127 %i4 = and i32 %i3, 1920 128 %i5 = or i32 %i1, %i4 129 %i6 = lshr i32 %x, 1 130 %i7 = and i32 %i6, 15 131 %i8 = or i32 %i2, %i7 132 %i9 = or i32 %i8, %i5 133 ret i32 %i9 134} 135 136define i32 @multiuse4(i32 %x) local_unnamed_addr { 137; CHECK-LABEL: @multiuse4( 138; CHECK-NEXT: [[I1:%.*]] = icmp sgt i32 [[X:%.*]], -1 139; CHECK-NEXT: br i1 [[I1]], label [[IF:%.*]], label [[ELSE:%.*]] 140; CHECK: if: 141; CHECK-NEXT: [[I:%.*]] = lshr i32 [[X]], 22 142; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 24 143; CHECK-NEXT: [[I3:%.*]] = lshr i32 [[X]], 22 144; CHECK-NEXT: [[I4:%.*]] = and i32 [[I3]], 480 145; CHECK-NEXT: [[I5:%.*]] = or disjoint i32 [[I4]], [[I2]] 146; CHECK-NEXT: br label [[END:%.*]] 147; CHECK: else: 148; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X]], 17 149; CHECK-NEXT: [[I9:%.*]] = and i32 [[TMP1]], 16128 150; 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, 100663296 156 %i1 = icmp sgt i32 %x, -1 157 br i1 %i1, label %if, label %else 158 159if: 160 %i2 = lshr exact i32 %i, 22 161 %i3 = lshr i32 %x, 22 162 %i4 = and i32 %i3, 480 163 %i5 = or i32 %i4, %i2 164 br label %end 165 166else: 167 %i6 = lshr exact i32 %i, 17 168 %i7 = lshr i32 %x, 17 169 %i8 = and i32 %i7, 15360 170 %i9 = or i32 %i8, %i6 171 br label %end 172 173end: 174 %i10 = phi i32 [ %i5, %if ], [ %i9, %else ] 175 ret i32 %i10 176} 177 178define i32 @multiuse5(i32 %x) local_unnamed_addr { 179; CHECK-LABEL: @multiuse5( 180; CHECK-NEXT: [[I:%.*]] = shl i32 [[X:%.*]], 5 181; CHECK-NEXT: [[I1:%.*]] = icmp sgt i32 [[X]], -1 182; CHECK-NEXT: br i1 [[I1]], label [[IF:%.*]], label [[ELSE:%.*]] 183; CHECK: if: 184; CHECK-NEXT: [[I2:%.*]] = and i32 [[I]], 21760 185; CHECK-NEXT: [[I3:%.*]] = shl i32 [[X]], 5 186; CHECK-NEXT: [[I4:%.*]] = and i32 [[I3]], 43520 187; CHECK-NEXT: [[I5:%.*]] = or disjoint i32 [[I4]], [[I2]] 188; CHECK-NEXT: br label [[END:%.*]] 189; CHECK: else: 190; CHECK-NEXT: [[I6:%.*]] = and i32 [[I]], 5570560 191; CHECK-NEXT: [[I7:%.*]] = shl i32 [[X]], 5 192; CHECK-NEXT: [[I8:%.*]] = and i32 [[I7]], 11141120 193; 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, 5 200 %i1 = icmp sgt i32 %x, -1 201 br i1 %i1, label %if, label %else 202 203if: 204 %i2 = and i32 %i, 21760 205 %i3 = and i32 %x, 1360 206 %i4 = shl nuw nsw i32 %i3, 5 207 %i5 = or i32 %i4, %i2 208 br label %end 209 210else: 211 %i6 = and i32 %i, 5570560 212 %i7 = and i32 %x, 348160 213 %i8 = shl nuw nsw i32 %i7, 5 214 %i9 = or i32 %i8, %i6 215 br label %end 216 217end: 218 %i10 = phi i32 [ %i5, %if ], [ %i9, %else ] 219 ret i32 %i10 220} 221 222define i32 @shl_mask(i32 %x) { 223; CHECK-LABEL: @shl_mask( 224; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255 225; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8 226; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[Z]], [[S]] 227; CHECK-NEXT: ret i32 [[R]] 228; 229 %z = and i32 %x, 255 230 %s = shl i32 %z, 8 231 %r = or i32 %z, %s 232 ret i32 %r 233} 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:%.*]], 255 238; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 7 239; CHECK-NEXT: [[R:%.*]] = or i32 [[Z]], [[S]] 240; CHECK-NEXT: ret i32 [[R]] 241; 242 %z = and i32 %x, 255 243 %s = shl i32 %z, 7 244 %r = or i32 %z, %s 245 ret i32 %r 246} 247 248define i37 @shl_mask_weird_type(i37 %x) { 249; CHECK-LABEL: @shl_mask_weird_type( 250; CHECK-NEXT: [[Z:%.*]] = and i37 [[X:%.*]], 255 251; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i37 [[Z]], 8 252; CHECK-NEXT: [[R:%.*]] = or disjoint i37 [[Z]], [[S]] 253; CHECK-NEXT: ret i37 [[R]] 254; 255 %z = and i37 %x, 255 256 %s = shl i37 %z, 8 257 %r = or i37 %z, %s 258 ret i37 %r 259} 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:%.*]], 255 264; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8 265; CHECK-NEXT: store i32 [[S]], ptr [[P:%.*]], align 4 266; CHECK-NEXT: [[R:%.*]] = or disjoint i32 [[Z]], [[S]] 267; CHECK-NEXT: ret i32 [[R]] 268; 269 %z = and i32 %x, 255 270 %s = shl i32 %z, 8 271 store i32 %s, ptr %p, align 4 272 %r = or i32 %z, %s 273 ret i32 %r 274} 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:%.*]], 255 281; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Z]], 65537 282; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8 283; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[S]] 284; CHECK-NEXT: ret i32 [[R]] 285; 286 %z = and i32 %x, 255 287 %m = mul i32 %z, 65537 288 %s = shl i32 %z, 8 289 %r = or i32 %m, %s 290 ret i32 %r 291} 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:%.*]], 255 296; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Z]], 65535 297; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8 298; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[S]] 299; CHECK-NEXT: ret i32 [[R]] 300; 301 %z = and i32 %x, 255 302 %m = mul i32 %z, 65535 303 %s = shl i32 %z, 8 304 %r = or i32 %m, %s 305 ret i32 %r 306} 307