1; RUN: opt -S -instcombine < %s | FileCheck %s 2 3define i32 @or_and_shifts1(i32 %x) { 4; CHECK-LABEL: @or_and_shifts1( 5; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 6; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 8 7; CHECK-NEXT: [[TMP3:%.*]] = shl i32 %x, 5 8; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 32 9; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] 10; CHECK-NEXT: ret i32 [[TMP5]] 11; 12 %1 = shl i32 %x, 3 13 %2 = and i32 %1, 15 14 %3 = shl i32 %x, 5 15 %4 = and i32 %3, 60 16 %5 = or i32 %2, %4 17 ret i32 %5 18} 19 20define i32 @or_and_shifts2(i32 %x) { 21; CHECK-LABEL: @or_and_shifts2( 22; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 23; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 896 24; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 %x, 4 25; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 7 26; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] 27; CHECK-NEXT: ret i32 [[TMP5]] 28; 29 %1 = shl i32 %x, 3 30 %2 = and i32 %1, 896 31 %3 = lshr i32 %x, 4 32 %4 = and i32 %3, 7 33 %5 = or i32 %2, %4 34 ret i32 %5 35} 36 37define i32 @or_and_shift_shift_and(i32 %x) { 38; CHECK-LABEL: @or_and_shift_shift_and( 39; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3 40; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 56 41; CHECK-NEXT: [[TMP3:%.*]] = shl i32 %x, 2 42; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 28 43; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]] 44; CHECK-NEXT: ret i32 [[TMP5]] 45; 46 %1 = and i32 %x, 7 47 %2 = shl i32 %1, 3 48 %3 = shl i32 %x, 2 49 %4 = and i32 %3, 28 50 %5 = or i32 %2, %4 51 ret i32 %5 52} 53 54define i32 @multiuse1(i32 %x) { 55; CHECK-LABEL: @multiuse1( 56; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 6 57; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 384 58; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 %x, 1 59; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 3 60; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP4]], [[TMP2]] 61; CHECK-NEXT: ret i32 [[TMP5]] 62; 63 %1 = and i32 %x, 2 64 %2 = and i32 %x, 4 65 %3 = shl nuw nsw i32 %1, 6 66 %4 = lshr exact i32 %1, 1 67 %5 = shl nuw nsw i32 %2, 6 68 %6 = lshr exact i32 %2, 1 69 %7 = or i32 %3, %5 70 %8 = or i32 %4, %6 71 %9 = or i32 %8, %7 72 ret i32 %9 73} 74 75define i32 @multiuse2(i32 %x) { 76; CHECK-LABEL: @multiuse2( 77; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 1 78; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 12 79; CHECK-NEXT: [[TMP3:%.*]] = shl i32 %x, 8 80; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 24576 81; CHECK-NEXT: [[TMP5:%.*]] = shl i32 %x, 8 82; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 7680 83; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP4]], [[TMP6]] 84; CHECK-NEXT: [[TMP8:%.*]] = shl i32 %x, 1 85; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 240 86; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP2]], [[TMP9]] 87; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP7]], [[TMP10]] 88; CHECK-NEXT: ret i32 [[TMP11]] 89; 90 %1 = and i32 %x, 6 91 %2 = shl nuw nsw i32 %1, 8 92 %3 = shl nuw nsw i32 %1, 1 93 %4 = and i32 %x, 24 94 %5 = shl nuw nsw i32 %4, 8 95 %6 = shl nuw nsw i32 %4, 1 96 %7 = and i32 %x, 96 97 %8 = shl nuw nsw i32 %7, 8 98 %9 = shl nuw nsw i32 %7, 1 99 %10 = or i32 %2, %5 100 %11 = or i32 %8, %10 101 %12 = or i32 %9, %6 102 %13 = or i32 %3, %12 103 %14 = or i32 %11, %13 104 ret i32 %14 105} 106 107define i32 @multiuse3(i32 %x) { 108; CHECK-LABEL: @multiuse3( 109; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 96 110; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 6 111; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i32 [[TMP1]], 1 112; CHECK-NEXT: [[TMP4:%.*]] = shl i32 %x, 6 113; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1920 114; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP2]], [[TMP5]] 115; CHECK-NEXT: [[TMP7:%.*]] = lshr i32 %x, 1 116; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], 15 117; CHECK-NEXT: [[TMP9:%.*]] = or i32 [[TMP3]], [[TMP8]] 118; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP6]] 119; CHECK-NEXT: ret i32 [[TMP10]] 120; 121 %1 = and i32 %x, 96 122 %2 = shl nuw nsw i32 %1, 6 123 %3 = lshr exact i32 %1, 1 124 %4 = shl i32 %x, 6 125 %5 = and i32 %4, 1920 126 %6 = or i32 %2, %5 127 %7 = lshr i32 %x, 1 128 %8 = and i32 %7, 15 129 %9 = or i32 %3, %8 130 %10 = or i32 %9, %6 131 ret i32 %10 132} 133 134define i32 @multiuse4(i32 %x) local_unnamed_addr #0 { 135; CHECK-LABEL: @multiuse4( 136; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 100663296 137; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 %x, -1 138; CHECK-NEXT: br i1 [[TMP2]], label %if, label %else 139; CHECK: {{.*}}if:{{.*}} 140; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i32 [[TMP1]], 22 141; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 %x, 22 142; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 480 143; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[TMP3]] 144; CHECK-NEXT: br label %end 145; CHECK: {{.*}}else:{{.*}} 146; CHECK-NEXT: [[TMP7:%.*]] = lshr exact i32 [[TMP1]], 17 147; CHECK-NEXT: [[TMP8:%.*]] = lshr i32 %x, 17 148; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 15360 149; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP7]] 150; CHECK-NEXT: br label %end 151; CHECK: {{.*}}end{{.*}} 152; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ [[TMP6]], %if ], [ [[TMP10]], %else ] 153; CHECK-NEXT: ret i32 [[TMP11]] 154; 155 %1 = and i32 %x, 100663296 156 %2 = icmp sgt i32 %x, -1 157 br i1 %2, label %if, label %else 158 159if: 160 %3 = lshr exact i32 %1, 22 161 %4 = lshr i32 %x, 22 162 %5 = and i32 %4, 480 163 %6 = or i32 %5, %3 164 br label %end 165 166else: 167 %7 = lshr exact i32 %1, 17 168 %8 = lshr i32 %x, 17 169 %9 = and i32 %8, 15360 170 %10 = or i32 %9, %7 171 br label %end 172 173end: 174 %11 = phi i32 [ %6, %if ], [ %10, %else ] 175 ret i32 %11 176} 177 178define i32 @multiuse5(i32 %x) local_unnamed_addr #0 { 179; CHECK-LABEL: @multiuse5( 180; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 5 181; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 %x, -1 182; CHECK-NEXT: br i1 [[TMP2]], label %if, label %else 183; CHECK: {{.*}}if:{{.*}} 184; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP1]], 21760 185; CHECK-NEXT: [[TMP4:%.*]] = shl i32 %x, 5 186; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 43520 187; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[TMP3]] 188; CHECK-NEXT: br label %end 189; CHECK: {{.*}}else:{{.*}} 190; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP1]], 5570560 191; CHECK-NEXT: [[TMP8:%.*]] = shl i32 %x, 5 192; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 11141120 193; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP7]] 194; CHECK-NEXT: br label %end 195; CHECK: {{.*}}end{{.*}} 196; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ [[TMP6]], %if ], [ [[TMP10]], %else ] 197; CHECK-NEXT: ret i32 [[TMP11]] 198; 199 %1 = shl i32 %x, 5 200 %2 = icmp sgt i32 %x, -1 201 br i1 %2, label %if, label %else 202 203if: 204 %3 = and i32 %1, 21760 205 %4 = and i32 %x, 1360 206 %5 = shl nuw nsw i32 %4, 5 207 %6 = or i32 %5, %3 208 br label %end 209 210else: 211 %7 = and i32 %1, 5570560 212 %8 = and i32 %x, 348160 213 %9 = shl nuw nsw i32 %8, 5 214 %10 = or i32 %9, %7 215 br label %end 216 217end: 218 %11 = phi i32 [ %6, %if ], [ %10, %else ] 219 ret i32 %11 220} 221 222