1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4define i8 @shl_or(i8 %x) { 5; CHECK-LABEL: define i8 @shl_or 6; CHECK-SAME: (i8 [[X:%.*]]) { 7; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] 8; CHECK-NEXT: ret i8 [[BINOP]] 9; 10 %shift = shl i8 16, %x 11 %add = add i8 %x, 1 12 %shift2 = shl i8 3, %add 13 %binop = or i8 %shift, %shift2 14 ret i8 %binop 15} 16 17define i8 @lshr_or(i8 %x) { 18; CHECK-LABEL: define i8 @lshr_or 19; CHECK-SAME: (i8 [[X:%.*]]) { 20; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 17, [[X]] 21; CHECK-NEXT: ret i8 [[BINOP]] 22; 23 %shift = lshr i8 16, %x 24 %add = add i8 %x, 1 25 %shift2 = lshr i8 3, %add 26 %binop = or i8 %shift, %shift2 27 ret i8 %binop 28} 29 30define i8 @ashr_or(i8 %x) { 31; CHECK-LABEL: define i8 @ashr_or 32; CHECK-SAME: (i8 [[X:%.*]]) { 33; CHECK-NEXT: [[BINOP:%.*]] = ashr i8 -64, [[X]] 34; CHECK-NEXT: ret i8 [[BINOP]] 35; 36 %shift = ashr i8 -64, %x 37 %add = add i8 %x, 1 38 %shift2 = ashr i8 -128, %add 39 %binop = or i8 %shift, %shift2 40 ret i8 %binop 41} 42 43define i8 @shl_xor(i8 %x) { 44; CHECK-LABEL: define i8 @shl_xor 45; CHECK-SAME: (i8 [[X:%.*]]) { 46; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] 47; CHECK-NEXT: ret i8 [[BINOP]] 48; 49 %shift = shl i8 16, %x 50 %add = add i8 %x, 1 51 %shift2 = shl i8 3, %add 52 %binop = xor i8 %shift, %shift2 53 ret i8 %binop 54} 55 56define i8 @lshr_xor(i8 %x) { 57; CHECK-LABEL: define i8 @lshr_xor 58; CHECK-SAME: (i8 [[X:%.*]]) { 59; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 17, [[X]] 60; CHECK-NEXT: ret i8 [[BINOP]] 61; 62 %shift = lshr i8 16, %x 63 %add = add i8 %x, 1 64 %shift2 = lshr i8 3, %add 65 %binop = xor i8 %shift, %shift2 66 ret i8 %binop 67} 68 69define i8 @ashr_xor(i8 %x) { 70; CHECK-LABEL: define i8 @ashr_xor 71; CHECK-SAME: (i8 [[X:%.*]]) { 72; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 96, [[X]] 73; CHECK-NEXT: ret i8 [[BINOP]] 74; 75 %shift = ashr i8 -128, %x 76 %add = add i8 %x, 1 77 %shift2 = ashr i8 -64, %add 78 %binop = xor i8 %shift, %shift2 79 ret i8 %binop 80} 81 82define i8 @shl_and(i8 %x) { 83; CHECK-LABEL: define i8 @shl_and 84; CHECK-SAME: (i8 [[X:%.*]]) { 85; CHECK-NEXT: [[BINOP:%.*]] = shl i8 16, [[X]] 86; CHECK-NEXT: ret i8 [[BINOP]] 87; 88 %shift = shl i8 48, %x 89 %add = add i8 %x, 1 90 %shift2 = shl i8 8, %add 91 %binop = and i8 %shift, %shift2 92 ret i8 %binop 93} 94 95define i8 @lshr_and(i8 %x) { 96; CHECK-LABEL: define i8 @lshr_and 97; CHECK-SAME: (i8 [[X:%.*]]) { 98; CHECK-NEXT: [[BINOP:%.*]] = lshr i8 32, [[X]] 99; CHECK-NEXT: ret i8 [[BINOP]] 100; 101 %shift = lshr i8 48, %x 102 %add = add i8 %x, 1 103 %shift2 = lshr i8 64, %add 104 %binop = and i8 %shift, %shift2 105 ret i8 %binop 106} 107 108define i8 @ashr_and(i8 %x) { 109; CHECK-LABEL: define i8 @ashr_and 110; CHECK-SAME: (i8 [[X:%.*]]) { 111; CHECK-NEXT: [[BINOP:%.*]] = ashr i8 -64, [[X]] 112; CHECK-NEXT: ret i8 [[BINOP]] 113; 114 %shift = ashr i8 -64, %x 115 %add = add i8 %x, 1 116 %shift2 = ashr i8 -128, %add 117 %binop = and i8 %shift, %shift2 118 ret i8 %binop 119} 120 121define i8 @shl_add(i8 %x) { 122; CHECK-LABEL: define i8 @shl_add 123; CHECK-SAME: (i8 [[X:%.*]]) { 124; CHECK-NEXT: [[BINOP:%.*]] = shl i8 30, [[X]] 125; CHECK-NEXT: ret i8 [[BINOP]] 126; 127 %shift = shl i8 16, %x 128 %add = add i8 %x, 1 129 %shift2 = shl i8 7, %add 130 %binop = add i8 %shift, %shift2 131 ret i8 %binop 132} 133 134define i8 @lshr_add_fail(i8 %x) { 135; CHECK-LABEL: define i8 @lshr_add_fail 136; CHECK-SAME: (i8 [[X:%.*]]) { 137; CHECK-NEXT: [[SHIFT:%.*]] = lshr i8 16, [[X]] 138; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 139; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 7, [[ADD]] 140; CHECK-NEXT: [[BINOP:%.*]] = add nuw nsw i8 [[SHIFT]], [[SHIFT2]] 141; CHECK-NEXT: ret i8 [[BINOP]] 142; 143 %shift = lshr i8 16, %x 144 %add = add i8 %x, 1 145 %shift2 = lshr i8 7, %add 146 %binop = add i8 %shift, %shift2 147 ret i8 %binop 148} 149 150define i8 @ashr_add_fail(i8 %x) { 151; CHECK-LABEL: define i8 @ashr_add_fail 152; CHECK-SAME: (i8 [[X:%.*]]) { 153; CHECK-NEXT: [[SHIFT:%.*]] = ashr exact i8 -128, [[X]] 154; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 155; CHECK-NEXT: [[SHIFT2:%.*]] = ashr exact i8 -128, [[ADD]] 156; CHECK-NEXT: [[BINOP:%.*]] = add i8 [[SHIFT]], [[SHIFT2]] 157; CHECK-NEXT: ret i8 [[BINOP]] 158; 159 %shift = ashr i8 -128, %x 160 %add = add i8 %x, 1 161 %shift2 = ashr i8 -128, %add 162 %binop = add i8 %shift, %shift2 163 ret i8 %binop 164} 165 166define i8 @shl_or_commuted(i8 %x) { 167; CHECK-LABEL: define i8 @shl_or_commuted 168; CHECK-SAME: (i8 [[X:%.*]]) { 169; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] 170; CHECK-NEXT: ret i8 [[BINOP]] 171; 172 %shift = shl i8 16, %x 173 %add = add i8 %x, 1 174 %shift2 = shl i8 3, %add 175 %binop = or i8 %shift2, %shift 176 ret i8 %binop 177} 178 179define <2 x i8> @shl_or_splat(<2 x i8> %x) { 180; CHECK-LABEL: define <2 x i8> @shl_or_splat 181; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 182; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> splat (i8 22), [[X]] 183; CHECK-NEXT: ret <2 x i8> [[BINOP]] 184; 185 %shift = shl <2 x i8> <i8 16, i8 16>, %x 186 %add = add <2 x i8> %x, <i8 1, i8 1> 187 %shift2 = shl <2 x i8> <i8 3, i8 3>, %add 188 %binop = or <2 x i8> %shift, %shift2 189 ret <2 x i8> %binop 190} 191 192define <2 x i8> @shl_or_non_splat(<2 x i8> %x) { 193; CHECK-LABEL: define <2 x i8> @shl_or_non_splat 194; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 195; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 60>, [[X]] 196; CHECK-NEXT: ret <2 x i8> [[BINOP]] 197; 198 %shift = shl <2 x i8> <i8 16, i8 32>, %x 199 %add = add <2 x i8> %x, <i8 1, i8 2> 200 %shift2 = shl <2 x i8> <i8 3, i8 7>, %add 201 %binop = or <2 x i8> %shift, %shift2 202 ret <2 x i8> %binop 203} 204 205define <2 x i8> @shl_or_poison_in_add(<2 x i8> %x) { 206; CHECK-LABEL: define <2 x i8> @shl_or_poison_in_add 207; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 208; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 poison>, [[X]] 209; CHECK-NEXT: ret <2 x i8> [[BINOP]] 210; 211 %shift = shl <2 x i8> <i8 16, i8 16>, %x 212 %add = add <2 x i8> %x, <i8 1, i8 poison> 213 %shift2 = shl <2 x i8> <i8 3, i8 3>, %add 214 %binop = or <2 x i8> %shift, %shift2 215 ret <2 x i8> %binop 216} 217 218define <2 x i8> @shl_or_poison_in_shift1(<2 x i8> %x) { 219; CHECK-LABEL: define <2 x i8> @shl_or_poison_in_shift1 220; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 221; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 poison>, [[X]] 222; CHECK-NEXT: ret <2 x i8> [[BINOP]] 223; 224 %shift = shl <2 x i8> <i8 16, i8 poison>, %x 225 %add = add <2 x i8> %x, <i8 1, i8 1> 226 %shift2 = shl <2 x i8> <i8 3, i8 3>, %add 227 %binop = or <2 x i8> %shift, %shift2 228 ret <2 x i8> %binop 229} 230 231define <2 x i8> @shl_or_poison_in_shift2(<2 x i8> %x) { 232; CHECK-LABEL: define <2 x i8> @shl_or_poison_in_shift2 233; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 234; CHECK-NEXT: [[BINOP:%.*]] = shl <2 x i8> <i8 22, i8 poison>, [[X]] 235; CHECK-NEXT: ret <2 x i8> [[BINOP]] 236; 237 %shift = shl <2 x i8> <i8 16, i8 16>, %x 238 %add = add <2 x i8> %x, <i8 1, i8 1> 239 %shift2 = shl <2 x i8> <i8 3, i8 poison>, %add 240 %binop = or <2 x i8> %shift, %shift2 241 ret <2 x i8> %binop 242} 243 244declare void @use(i8) 245 246define i8 @shl_or_multiuse(i8 %x) { 247; CHECK-LABEL: define i8 @shl_or_multiuse 248; CHECK-SAME: (i8 [[X:%.*]]) { 249; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] 250; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 251; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] 252; CHECK-NEXT: call void @use(i8 [[SHIFT]]) 253; CHECK-NEXT: call void @use(i8 [[ADD]]) 254; CHECK-NEXT: call void @use(i8 [[SHIFT2]]) 255; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] 256; CHECK-NEXT: ret i8 [[BINOP]] 257; 258 %shift = shl i8 16, %x 259 %add = add i8 %x, 1 260 %shift2 = shl i8 3, %add 261 call void @use(i8 %shift) 262 call void @use(i8 %add) 263 call void @use(i8 %shift2) 264 %binop = or i8 %shift, %shift2 265 ret i8 %binop 266} 267 268define i8 @mismatched_shifts(i8 %x) { 269; CHECK-LABEL: define i8 @mismatched_shifts 270; CHECK-SAME: (i8 [[X:%.*]]) { 271; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] 272; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 273; CHECK-NEXT: [[SHIFT2:%.*]] = lshr i8 3, [[ADD]] 274; CHECK-NEXT: [[BINOP:%.*]] = or disjoint i8 [[SHIFT]], [[SHIFT2]] 275; CHECK-NEXT: ret i8 [[BINOP]] 276; 277 %shift = shl i8 16, %x 278 %add = add i8 %x, 1 279 %shift2 = lshr i8 3, %add 280 %binop = or i8 %shift, %shift2 281 ret i8 %binop 282} 283 284define i8 @mismatched_ops(i8 %x, i8 %y) { 285; CHECK-LABEL: define i8 @mismatched_ops 286; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) { 287; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] 288; CHECK-NEXT: [[ADD:%.*]] = add i8 [[Y]], 1 289; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] 290; CHECK-NEXT: [[BINOP:%.*]] = or i8 [[SHIFT]], [[SHIFT2]] 291; CHECK-NEXT: ret i8 [[BINOP]] 292; 293 %shift = shl i8 16, %x 294 %add = add i8 %y, 1 295 %shift2 = shl i8 3, %add 296 %binop = or i8 %shift, %shift2 297 ret i8 %binop 298} 299 300define i8 @add_out_of_range(i8 %x) { 301; CHECK-LABEL: define i8 @add_out_of_range 302; CHECK-SAME: (i8 [[X:%.*]]) { 303; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] 304; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 32 305; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] 306; CHECK-NEXT: [[BINOP:%.*]] = or i8 [[SHIFT]], [[SHIFT2]] 307; CHECK-NEXT: ret i8 [[BINOP]] 308; 309 %shift = shl i8 16, %x 310 %add = add i8 %x, 32 311 %shift2 = shl i8 3, %add 312 %binop = or i8 %shift, %shift2 313 ret i8 %binop 314} 315 316define <2 x i8> @shl_or_non_splat_out_of_range(<2 x i8> %x) { 317; CHECK-LABEL: define <2 x i8> @shl_or_non_splat_out_of_range 318; CHECK-SAME: (<2 x i8> [[X:%.*]]) { 319; CHECK-NEXT: [[SHIFT:%.*]] = shl <2 x i8> <i8 16, i8 32>, [[X]] 320; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 32> 321; CHECK-NEXT: [[SHIFT2:%.*]] = shl <2 x i8> <i8 3, i8 7>, [[ADD]] 322; CHECK-NEXT: [[BINOP:%.*]] = or <2 x i8> [[SHIFT]], [[SHIFT2]] 323; CHECK-NEXT: ret <2 x i8> [[BINOP]] 324; 325 %shift = shl <2 x i8> <i8 16, i8 32>, %x 326 %add = add <2 x i8> %x, <i8 1, i8 32> 327 %shift2 = shl <2 x i8> <i8 3, i8 7>, %add 328 %binop = or <2 x i8> %shift, %shift2 329 ret <2 x i8> %binop 330} 331 332define i8 @shl_or_with_or_disjoint_instead_of_add(i8 %x) { 333; CHECK-LABEL: define i8 @shl_or_with_or_disjoint_instead_of_add 334; CHECK-SAME: (i8 [[X:%.*]]) { 335; CHECK-NEXT: [[BINOP:%.*]] = shl i8 22, [[X]] 336; CHECK-NEXT: ret i8 [[BINOP]] 337; 338 %shift = shl i8 16, %x 339 %add = or disjoint i8 %x, 1 340 %shift2 = shl i8 3, %add 341 %binop = or i8 %shift, %shift2 342 ret i8 %binop 343} 344 345define i8 @shl_or_with_or_instead_of_add(i8 %x) { 346; CHECK-LABEL: define i8 @shl_or_with_or_instead_of_add 347; CHECK-SAME: (i8 [[X:%.*]]) { 348; CHECK-NEXT: [[SHIFT:%.*]] = shl i8 16, [[X]] 349; CHECK-NEXT: [[ADD:%.*]] = or i8 [[X]], 1 350; CHECK-NEXT: [[SHIFT2:%.*]] = shl i8 3, [[ADD]] 351; CHECK-NEXT: [[BINOP:%.*]] = or i8 [[SHIFT]], [[SHIFT2]] 352; CHECK-NEXT: ret i8 [[BINOP]] 353; 354 %shift = shl i8 16, %x 355 %add = or i8 %x, 1 356 %shift2 = shl i8 3, %add 357 %binop = or i8 %shift, %shift2 358 ret i8 %binop 359} 360