1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3declare void @use8(i8) 4declare i64 @llvm.vscale.i64() 5declare i32 @llvm.vscale.i32() 6 7define i8 @srem_non_matching(i8 %X, i8 %Y) { 8; CHECK-LABEL: @srem_non_matching( 9; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 15 10; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[Y:%.*]], 5 11; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 12; CHECK-NEXT: ret i8 [[R]] 13; 14 %BO0 = mul nsw nuw i8 %X, 15 15 %BO1 = mul nsw nuw i8 %Y, 5 16 %r = srem i8 %BO0, %BO1 17 ret i8 %r 18} 19 20define i8 @urem_1_shl(i8 %X, i8 %Y) { 21; CHECK-LABEL: @urem_1_shl( 22; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 1, [[X:%.*]] 23; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i8 -1, [[Y:%.*]] 24; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[NOTMASK]], -1 25; CHECK-NEXT: [[R:%.*]] = and i8 [[BO0]], [[TMP1]] 26; CHECK-NEXT: ret i8 [[R]] 27; 28 %BO0 = shl nsw nuw i8 1, %X 29 %BO1 = shl nsw nuw i8 1, %Y 30 %r = urem i8 %BO0, %BO1 31 ret i8 %r 32} 33 34define <vscale x 16 x i8> @urem_XY_XZ_with_CY_rem_CZ_eq_0_scalable(<vscale x 16 x i8> %X) { 35; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0_scalable( 36; CHECK-NEXT: ret <vscale x 16 x i8> zeroinitializer 37; 38 %BO0 = mul nuw <vscale x 16 x i8> %X, splat (i8 15) 39 %BO1 = mul <vscale x 16 x i8> %X, splat (i8 5) 40 %r = urem <vscale x 16 x i8> %BO0, %BO1 41 ret <vscale x 16 x i8> %r 42} 43 44define i8 @urem_XY_XZ_with_CY_rem_CZ_eq_0(i8 %X) { 45; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0( 46; CHECK-NEXT: ret i8 0 47; 48 %BO0 = mul nuw i8 %X, 15 49 %BO1 = mul i8 %X, 5 50 %r = urem i8 %BO0, %BO1 51 ret i8 %r 52} 53 54define i8 @urem_XY_XZ_with_CY_rem_CZ_eq_0_with_shl(i8 %X) { 55; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0_with_shl( 56; CHECK-NEXT: ret i8 0 57; 58 %BO0 = shl nuw i8 15, %X 59 %BO1 = shl i8 5, %X 60 %r = urem i8 %BO0, %BO1 61 ret i8 %r 62} 63 64define i8 @urem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag(i8 %X) { 65; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag( 66; CHECK-NEXT: [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 15 67; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], 5 68; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 69; CHECK-NEXT: ret i8 [[R]] 70; 71 %BO0 = mul nsw i8 %X, 15 72 %BO1 = mul nsw nuw i8 %X, 5 73 %r = urem i8 %BO0, %BO1 74 ret i8 %r 75} 76 77define i8 @urem_XY_XZ_with_CY_lt_CZ(i8 %X) { 78; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ( 79; CHECK-NEXT: [[R:%.*]] = mul nuw i8 [[X:%.*]], 3 80; CHECK-NEXT: ret i8 [[R]] 81; 82 %BO0 = mul i8 %X, 3 83 %BO1 = mul nuw i8 %X, 12 84 %r = urem i8 %BO0, %BO1 85 ret i8 %r 86} 87 88define i8 @urem_XY_XZ_with_CY_lt_CZ_with_shl(i8 %X) { 89; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_with_shl( 90; CHECK-NEXT: [[R:%.*]] = shl nuw i8 3, [[X:%.*]] 91; CHECK-NEXT: ret i8 [[R]] 92; 93 %BO0 = shl i8 3, %X 94 %BO1 = shl nuw i8 12, %X 95 %r = urem i8 %BO0, %BO1 96 ret i8 %r 97} 98 99define <2 x i8> @urem_XY_XZ_with_CY_lt_CZ_with_nsw_out(<2 x i8> %X) { 100; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_with_nsw_out( 101; CHECK-NEXT: [[R:%.*]] = shl nuw nsw <2 x i8> [[X:%.*]], splat (i8 2) 102; CHECK-NEXT: ret <2 x i8> [[R]] 103; 104 %BO0 = shl nsw <2 x i8> %X, <i8 2, i8 2> 105 %BO1 = mul nuw <2 x i8> %X, <i8 12, i8 12> 106 %r = urem <2 x i8> %BO0, %BO1 107 ret <2 x i8> %r 108} 109 110define i8 @urem_XY_XZ_with_CY_lt_CZ_no_nsw_out(i8 %X) { 111; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_no_nsw_out( 112; CHECK-NEXT: [[R:%.*]] = mul nuw i8 [[X:%.*]], 3 113; CHECK-NEXT: ret i8 [[R]] 114; 115 %BO0 = mul nuw i8 %X, 3 116 %BO1 = shl nsw nuw i8 %X, 3 117 %r = urem i8 %BO0, %BO1 118 ret i8 %r 119} 120 121define i8 @urem_XY_XZ_with_CY_lt_CZ_fail_missing_flag(i8 %X) { 122; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_fail_missing_flag( 123; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 3 124; CHECK-NEXT: [[BO1:%.*]] = mul nsw i8 [[X]], 12 125; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 126; CHECK-NEXT: ret i8 [[R]] 127; 128 %BO0 = mul nuw nsw i8 %X, 3 129 %BO1 = mul nsw i8 %X, 12 130 %r = urem i8 %BO0, %BO1 131 ret i8 %r 132} 133 134define i8 @urem_XY_XZ_with_CY_gt_CZ(i8 %X) { 135; CHECK-LABEL: @urem_XY_XZ_with_CY_gt_CZ( 136; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i8 [[X:%.*]], 3 137; CHECK-NEXT: ret i8 [[R]] 138; 139 %BO0 = mul nuw i8 %X, 21 140 %BO1 = mul i8 %X, 6 141 %r = urem i8 %BO0, %BO1 142 ret i8 %r 143} 144 145define i8 @urem_XY_XZ_with_CY_gt_CZ_fail_missing_flag(i8 %X) { 146; CHECK-LABEL: @urem_XY_XZ_with_CY_gt_CZ_fail_missing_flag( 147; CHECK-NEXT: [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 21 148; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], 6 149; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 150; CHECK-NEXT: ret i8 [[R]] 151; 152 %BO0 = mul nsw i8 %X, 21 153 %BO1 = mul nsw nuw i8 %X, 6 154 %r = urem i8 %BO0, %BO1 155 ret i8 %r 156} 157 158define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(i8 %X, i8 %Y, i8 %Z) { 159; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ( 160; CHECK-NEXT: [[BO0:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 161; CHECK-NEXT: [[BO1:%.*]] = mul nuw i8 [[Z:%.*]], [[X]] 162; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 163; CHECK-NEXT: ret i8 [[R]] 164; 165 %BO0 = mul nuw i8 %X, %Y 166 %BO1 = mul nuw i8 %Z, %X 167 %r = urem i8 %BO0, %BO1 168 ret i8 %r 169} 170 171define i8 @urem_XY_XZ_with_CX_Y_Z_is_mul_X_RemYZ(i8 %Y, i8 %Z) { 172; CHECK-LABEL: @urem_XY_XZ_with_CX_Y_Z_is_mul_X_RemYZ( 173; CHECK-NEXT: [[BO0:%.*]] = mul nuw i8 [[Y:%.*]], 10 174; CHECK-NEXT: [[BO1:%.*]] = shl nuw i8 10, [[Z:%.*]] 175; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 176; CHECK-NEXT: ret i8 [[R]] 177; 178 %BO0 = mul nuw i8 10, %Y 179 %BO1 = shl nuw i8 10, %Z 180 %r = urem i8 %BO0, %BO1 181 ret i8 %r 182} 183 184define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out1(i8 %X, i8 %Y, i8 %Z) { 185; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out1( 186; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]] 187; CHECK-NEXT: [[BO1:%.*]] = shl nuw i8 [[X]], [[Z:%.*]] 188; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 189; CHECK-NEXT: ret i8 [[R]] 190; 191 %BO0 = mul nuw nsw i8 %X, %Y 192 %BO1 = shl nuw i8 %X, %Z 193 %r = urem i8 %BO0, %BO1 194 ret i8 %r 195} 196 197define <2 x i8> @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out2(<2 x i8> %X, <2 x i8> %Y, <2 x i8> %Z) { 198; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out2( 199; CHECK-NEXT: [[BO0:%.*]] = shl nuw <2 x i8> [[Y:%.*]], [[X:%.*]] 200; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw <2 x i8> [[Z:%.*]], [[X]] 201; CHECK-NEXT: [[R:%.*]] = urem <2 x i8> [[BO0]], [[BO1]] 202; CHECK-NEXT: ret <2 x i8> [[R]] 203; 204 %BO0 = shl nuw <2 x i8> %Y, %X 205 %BO1 = shl nuw nsw <2 x i8> %Z, %X 206 %r = urem <2 x i8> %BO0, %BO1 207 ret <2 x i8> %r 208} 209 210define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_reused1(i8 %X, i8 %Y, i8 %Z) { 211; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_reused1( 212; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]] 213; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]] 214; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 215; CHECK-NEXT: call void @use8(i8 [[BO0]]) 216; CHECK-NEXT: ret i8 [[R]] 217; 218 %BO0 = mul nsw nuw i8 %X, %Y 219 %BO1 = mul nsw nuw i8 %X, %Z 220 %r = urem i8 %BO0, %BO1 221 call void @use8(i8 %BO0) 222 ret i8 %r 223} 224 225define <2 x i8> @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(<2 x i8> %X, <2 x i8> %Y, <2 x i8> %Z) { 226; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1( 227; CHECK-NEXT: [[BO0:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[Y:%.*]] 228; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw <2 x i8> [[X]], [[Z:%.*]] 229; CHECK-NEXT: [[R:%.*]] = urem <2 x i8> [[BO0]], [[BO1]] 230; CHECK-NEXT: ret <2 x i8> [[R]] 231; 232 %BO0 = mul nsw <2 x i8> %X, %Y 233 %BO1 = mul nsw nuw <2 x i8> %X, %Z 234 %r = urem <2 x i8> %BO0, %BO1 235 ret <2 x i8> %r 236} 237 238define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(i8 %X, i8 %Y, i8 %Z) { 239; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2( 240; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]] 241; CHECK-NEXT: [[BO1:%.*]] = shl nsw i8 [[X]], [[Z:%.*]] 242; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 243; CHECK-NEXT: ret i8 [[R]] 244; 245 %BO0 = mul nsw nuw i8 %X, %Y 246 %BO1 = shl nsw i8 %X, %Z 247 %r = urem i8 %BO0, %BO1 248 ret i8 %r 249} 250 251;; Signed Verions 252define <vscale x 16 x i8> @srem_XY_XZ_with_CY_rem_CZ_eq_0_scalable(<vscale x 16 x i8> %X) { 253; CHECK-LABEL: @srem_XY_XZ_with_CY_rem_CZ_eq_0_scalable( 254; CHECK-NEXT: ret <vscale x 16 x i8> zeroinitializer 255; 256 %BO0 = mul nsw <vscale x 16 x i8> %X, splat (i8 15) 257 %BO1 = mul <vscale x 16 x i8> %X, splat (i8 5) 258 %r = srem <vscale x 16 x i8> %BO0, %BO1 259 ret <vscale x 16 x i8> %r 260} 261 262define i8 @srem_XY_XZ_with_CY_rem_CZ_eq_0(i8 %X) { 263; CHECK-LABEL: @srem_XY_XZ_with_CY_rem_CZ_eq_0( 264; CHECK-NEXT: ret i8 0 265; 266 %BO0 = mul nsw i8 %X, 9 267 %BO1 = mul i8 %X, 3 268 %r = srem i8 %BO0, %BO1 269 ret i8 %r 270} 271 272define i8 @srem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag(i8 %X) { 273; CHECK-LABEL: @srem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag( 274; CHECK-NEXT: [[BO0:%.*]] = mul nuw i8 [[X:%.*]], 9 275; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], 3 276; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 277; CHECK-NEXT: ret i8 [[R]] 278; 279 %BO0 = mul nuw i8 %X, 9 280 %BO1 = mul nsw nuw i8 %X, 3 281 %r = srem i8 %BO0, %BO1 282 ret i8 %r 283} 284 285define <2 x i8> @srem_XY_XZ_with_CY_lt_CZ(<2 x i8> %X) { 286; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ( 287; CHECK-NEXT: [[R:%.*]] = shl nsw <2 x i8> [[X:%.*]], splat (i8 3) 288; CHECK-NEXT: ret <2 x i8> [[R]] 289; 290 %BO0 = shl <2 x i8> %X, <i8 3, i8 3> 291 %BO1 = mul nsw <2 x i8> %X, <i8 15, i8 15> 292 %r = srem <2 x i8> %BO0, %BO1 293 ret <2 x i8> %r 294} 295 296define i8 @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out(i8 %X) { 297; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out( 298; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i8 [[X:%.*]], 5 299; CHECK-NEXT: ret i8 [[R]] 300; 301 %BO0 = mul nuw i8 %X, 5 302 %BO1 = mul nsw i8 %X, 15 303 %r = srem i8 %BO0, %BO1 304 ret i8 %r 305} 306 307define <2 x i8> @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out_with_shl(<2 x i8> %X) { 308; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out_with_shl( 309; CHECK-NEXT: [[R:%.*]] = shl nuw nsw <2 x i8> splat (i8 3), [[X:%.*]] 310; CHECK-NEXT: ret <2 x i8> [[R]] 311; 312 %BO0 = shl nuw <2 x i8> <i8 3, i8 3>, %X 313 %BO1 = shl nsw <2 x i8> <i8 15, i8 15>, %X 314 %r = srem <2 x i8> %BO0, %BO1 315 ret <2 x i8> %r 316} 317 318define i8 @srem_XY_XZ_with_CY_lt_CZ_no_nsw_out(i8 %X) { 319; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_no_nsw_out( 320; CHECK-NEXT: [[R:%.*]] = mul nsw i8 [[X:%.*]], 5 321; CHECK-NEXT: ret i8 [[R]] 322; 323 %BO0 = mul nsw i8 %X, 5 324 %BO1 = shl nsw nuw i8 %X, 4 325 %r = srem i8 %BO0, %BO1 326 ret i8 %r 327} 328 329define i8 @srem_XY_XZ_with_CY_lt_CZ_fail_missing_flag(i8 %X) { 330; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_fail_missing_flag( 331; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 5 332; CHECK-NEXT: [[BO1:%.*]] = shl nuw i8 [[X]], 4 333; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 334; CHECK-NEXT: ret i8 [[R]] 335; 336 %BO0 = mul nuw nsw i8 %X, 5 337 %BO1 = shl nuw i8 %X, 4 338 %r = srem i8 %BO0, %BO1 339 ret i8 %r 340} 341 342define i8 @srem_XY_XZ_with_CY_gt_CZ(i8 %X) { 343; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ( 344; CHECK-NEXT: [[R:%.*]] = shl nsw i8 [[X:%.*]], 1 345; CHECK-NEXT: ret i8 [[R]] 346; 347 %BO0 = shl nsw i8 %X, 3 348 %BO1 = mul nsw i8 %X, 6 349 %r = srem i8 %BO0, %BO1 350 ret i8 %r 351} 352 353define i8 @srem_XY_XZ_with_CY_gt_CZ_with_nuw_out(i8 %X) { 354; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_with_nuw_out( 355; CHECK-NEXT: [[R:%.*]] = shl nuw nsw i8 [[X:%.*]], 2 356; CHECK-NEXT: ret i8 [[R]] 357; 358 %BO0 = mul nsw nuw i8 %X, 10 359 %BO1 = mul nsw i8 %X, 6 360 %r = srem i8 %BO0, %BO1 361 ret i8 %r 362} 363 364define <2 x i8> @srem_XY_XZ_with_CY_gt_CZ_no_nuw_out(<2 x i8> %X) { 365; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_no_nuw_out( 366; CHECK-NEXT: [[R:%.*]] = shl nsw <2 x i8> [[X:%.*]], splat (i8 1) 367; CHECK-NEXT: ret <2 x i8> [[R]] 368; 369 %BO0 = mul nsw <2 x i8> %X, <i8 10, i8 10> 370 %BO1 = shl nsw nuw <2 x i8> %X, <i8 3, i8 3> 371 %r = srem <2 x i8> %BO0, %BO1 372 ret <2 x i8> %r 373} 374 375define i8 @srem_XY_XZ_with_CY_gt_CZ_drop_nsw(i8 noundef %X) { 376; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_drop_nsw( 377; CHECK-NEXT: [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 127 378; CHECK-NEXT: [[BO1:%.*]] = shl nsw i8 [[X]], 7 379; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO1]], [[BO0]] 380; CHECK-NEXT: ret i8 [[R]] 381; 382 %BO0 = mul nsw i8 %X, 127 383 %BO1 = shl nsw i8 %X, 7 384 %r = srem i8 %BO1, %BO0 385 ret i8 %r 386} 387 388define i8 @srem_XY_XZ_with_CY_gt_CZ_drop_nsw_commuted(i8 noundef %X) { 389; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_drop_nsw_commuted( 390; CHECK-NEXT: [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 127 391; CHECK-NEXT: [[BO1:%.*]] = shl nsw i8 [[X]], 7 392; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 393; CHECK-NEXT: ret i8 [[R]] 394; 395 %BO0 = mul nsw i8 %X, 127 396 %BO1 = shl nsw i8 %X, 7 397 %r = srem i8 %BO0, %BO1 398 ret i8 %r 399} 400 401define i8 @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag1(i8 %X) { 402; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag1( 403; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 10 404; CHECK-NEXT: [[BO1:%.*]] = mul nuw i8 [[X]], 6 405; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 406; CHECK-NEXT: ret i8 [[R]] 407; 408 %BO0 = mul nsw nuw i8 %X, 10 409 %BO1 = mul nuw i8 %X, 6 410 %r = srem i8 %BO0, %BO1 411 ret i8 %r 412} 413 414define i8 @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag2(i8 %X) { 415; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag2( 416; CHECK-NEXT: [[BO0:%.*]] = shl nuw i8 [[X:%.*]], 4 417; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], 5 418; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 419; CHECK-NEXT: ret i8 [[R]] 420; 421 %BO0 = shl nuw i8 %X, 4 422 %BO1 = mul nsw nuw i8 %X, 5 423 %r = srem i8 %BO0, %BO1 424 ret i8 %r 425} 426 427define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(i8 %X, i8 %Y, i8 %Z) { 428; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ( 429; CHECK-NEXT: [[BO0:%.*]] = mul nsw i8 [[Y:%.*]], [[X:%.*]] 430; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]] 431; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 432; CHECK-NEXT: ret i8 [[R]] 433; 434 %BO0 = mul nsw i8 %Y, %X 435 %BO1 = mul nsw nuw i8 %X, %Z 436 %r = srem i8 %BO0, %BO1 437 ret i8 %r 438} 439 440define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nuw_out(i8 %X, i8 %Y, i8 %Z) { 441; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nuw_out( 442; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]] 443; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]] 444; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 445; CHECK-NEXT: ret i8 [[R]] 446; 447 %BO0 = mul nsw nuw i8 %Y, %X 448 %BO1 = mul nsw nuw i8 %Z, %X 449 %r = srem i8 %BO0, %BO1 450 ret i8 %r 451} 452 453define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_shl(i8 %X, i8 %Y, i8 %Z) { 454; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_shl( 455; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]] 456; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]] 457; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 458; CHECK-NEXT: ret i8 [[R]] 459; 460 %BO0 = shl nsw nuw i8 %X, %Y 461 %BO1 = shl nsw nuw i8 %X, %Z 462 %r = srem i8 %BO0, %BO1 463 ret i8 %r 464} 465 466 467define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(i8 %X, i8 %Y, i8 %Z) { 468; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1( 469; CHECK-NEXT: [[BO0:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]] 470; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]] 471; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 472; CHECK-NEXT: ret i8 [[R]] 473; 474 %BO0 = mul nuw i8 %X, %Y 475 %BO1 = mul nsw nuw i8 %X, %Z 476 %r = srem i8 %BO0, %BO1 477 ret i8 %r 478} 479 480define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(i8 %X, i8 %Y, i8 %Z) { 481; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2( 482; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]] 483; CHECK-NEXT: [[BO1:%.*]] = mul nuw i8 [[X]], [[Z:%.*]] 484; CHECK-NEXT: [[R:%.*]] = srem i8 [[BO0]], [[BO1]] 485; CHECK-NEXT: ret i8 [[R]] 486; 487 %BO0 = mul nsw nuw i8 %X, %Y 488 %BO1 = mul nuw i8 %X, %Z 489 %r = srem i8 %BO0, %BO1 490 ret i8 %r 491} 492 493define i8 @urem_shl_XY_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) { 494; CHECK-LABEL: @urem_shl_XY_shl_ZX_fail( 495; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]] 496; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]] 497; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 498; CHECK-NEXT: ret i8 [[R]] 499; 500 %BO0 = shl nuw nsw i8 %X, %Y 501 %BO1 = shl nuw nsw i8 %Z, %X 502 %r = urem i8 %BO0, %BO1 503 ret i8 %r 504} 505 506define i8 @urem_mul_XY_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) { 507; CHECK-LABEL: @urem_mul_XY_shl_ZX_fail( 508; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]] 509; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]] 510; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 511; CHECK-NEXT: ret i8 [[R]] 512; 513 %BO0 = mul nuw nsw i8 %X, %Y 514 %BO1 = shl nuw nsw i8 %Z, %X 515 %r = urem i8 %BO0, %BO1 516 ret i8 %r 517} 518 519define i8 @urem_shl_YX_shl_XZ_fail(i8 %X, i8 %Z, i8 %Y) { 520; CHECK-LABEL: @urem_shl_YX_shl_XZ_fail( 521; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]] 522; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]] 523; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 524; CHECK-NEXT: ret i8 [[R]] 525; 526 %BO0 = shl nuw nsw i8 %Y, %X 527 %BO1 = shl nuw nsw i8 %X, %Z 528 %r = urem i8 %BO0, %BO1 529 ret i8 %r 530} 531 532define i8 @urem_shl_YX_mul_XZ_fail(i8 %X, i8 %Z, i8 %Y) { 533; CHECK-LABEL: @urem_shl_YX_mul_XZ_fail( 534; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]] 535; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]] 536; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 537; CHECK-NEXT: ret i8 [[R]] 538; 539 %BO0 = shl nuw nsw i8 %Y, %X 540 %BO1 = mul nuw nsw i8 %X, %Z 541 %r = urem i8 %BO0, %BO1 542 ret i8 %r 543} 544 545define i8 @urem_shl_YX_mul_ZX_fail(i8 %X, i8 %Z, i8 %Y) { 546; CHECK-LABEL: @urem_shl_YX_mul_ZX_fail( 547; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]] 548; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]] 549; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 550; CHECK-NEXT: ret i8 [[R]] 551; 552 %BO0 = shl nuw nsw i8 %Y, %X 553 %BO1 = mul nuw nsw i8 %Z, %X 554 %r = urem i8 %BO0, %BO1 555 ret i8 %r 556} 557 558define i8 @urem_mul_YX_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) { 559; CHECK-LABEL: @urem_mul_YX_shl_ZX_fail( 560; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]] 561; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]] 562; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 563; CHECK-NEXT: ret i8 [[R]] 564; 565 %BO0 = mul nuw nsw i8 %Y, %X 566 %BO1 = shl nuw nsw i8 %Z, %X 567 %r = urem i8 %BO0, %BO1 568 ret i8 %r 569} 570 571define i8 @urem_shl_CXY_shl_ZCX_fail(i8 %Z, i8 %Y) { 572; CHECK-LABEL: @urem_shl_CXY_shl_ZCX_fail( 573; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 3, [[Y:%.*]] 574; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], 3 575; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 576; CHECK-NEXT: ret i8 [[R]] 577; 578 %BO0 = shl nuw nsw i8 3, %Y 579 %BO1 = shl nuw nsw i8 %Z, 3 580 %r = urem i8 %BO0, %BO1 581 ret i8 %r 582} 583 584define i8 @urem_shl_YCX_shl_CXZ_fail(i8 %Z, i8 %Y) { 585; CHECK-LABEL: @urem_shl_YCX_shl_CXZ_fail( 586; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], 3 587; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 3, [[Z:%.*]] 588; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 589; CHECK-NEXT: ret i8 [[R]] 590; 591 %BO0 = shl nuw nsw i8 %Y, 3 592 %BO1 = shl nuw nsw i8 3, %Z 593 %r = urem i8 %BO0, %BO1 594 ret i8 %r 595} 596 597define i8 @urem_shl_YCX_mul_ZCX_fail(i8 %Z, i8 %Y) { 598; CHECK-LABEL: @urem_shl_YCX_mul_ZCX_fail( 599; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], 3 600; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], 10 601; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 602; CHECK-NEXT: ret i8 [[R]] 603; 604 %BO0 = shl nuw nsw i8 %Y, 3 605 %BO1 = mul nuw nsw i8 %Z, 10 606 %r = urem i8 %BO0, %BO1 607 ret i8 %r 608} 609 610define i8 @urem_mul_YCX_shl_ZCX_fail(i8 %Z, i8 %Y) { 611; CHECK-LABEL: @urem_mul_YCX_shl_ZCX_fail( 612; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], 3 613; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], 3 614; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 615; CHECK-NEXT: ret i8 [[R]] 616; 617 %BO0 = mul nuw nsw i8 %Y, 3 618 %BO1 = shl nuw nsw i8 %Z, 3 619 %r = urem i8 %BO0, %BO1 620 ret i8 %r 621} 622 623define i8 @urem_shl_XCY_shl_CZX_fail(i8 %X) { 624; CHECK-LABEL: @urem_shl_XCY_shl_CZX_fail( 625; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], 3 626; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 6, [[X]] 627; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 628; CHECK-NEXT: ret i8 [[R]] 629; 630 %BO0 = shl nuw nsw i8 %X, 3 631 %BO1 = shl nuw nsw i8 6, %X 632 %r = urem i8 %BO0, %BO1 633 ret i8 %r 634} 635 636define i8 @urem_mul_XCY_shl_CZX_fail(i8 %X) { 637; CHECK-LABEL: @urem_mul_XCY_shl_CZX_fail( 638; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 6 639; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 3, [[X]] 640; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 641; CHECK-NEXT: ret i8 [[R]] 642; 643 %BO0 = mul nuw nsw i8 %X, 6 644 %BO1 = shl nuw nsw i8 3, %X 645 %r = urem i8 %BO0, %BO1 646 ret i8 %r 647} 648 649define i8 @urem_shl_CYX_shl_XCZ_fail(i8 %X) { 650; CHECK-LABEL: @urem_shl_CYX_shl_XCZ_fail( 651; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 3, [[X:%.*]] 652; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], 6 653; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 654; CHECK-NEXT: ret i8 [[R]] 655; 656 %BO0 = shl nuw nsw i8 3, %X 657 %BO1 = shl nuw nsw i8 %X, 6 658 %r = urem i8 %BO0, %BO1 659 ret i8 %r 660} 661 662define i8 @urem_shl_CYX_mul_XCZ_fail(i8 %X) { 663; CHECK-LABEL: @urem_shl_CYX_mul_XCZ_fail( 664; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 3, [[X:%.*]] 665; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], 10 666; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 667; CHECK-NEXT: ret i8 [[R]] 668; 669 %BO0 = shl nuw nsw i8 3, %X 670 %BO1 = mul nuw nsw i8 %X, 10 671 %r = urem i8 %BO0, %BO1 672 ret i8 %r 673} 674 675define i8 @urem_shl_XX_shl_ZX(i8 %X, i8 %Z) { 676; CHECK-LABEL: @urem_shl_XX_shl_ZX( 677; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]] 678; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]] 679; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 680; CHECK-NEXT: ret i8 [[R]] 681; 682 %BO0 = shl nuw nsw i8 %X, %X 683 %BO1 = shl nuw nsw i8 %Z, %X 684 %r = urem i8 %BO0, %BO1 685 ret i8 %r 686} 687 688define i8 @urem_shl_YX_shl_XX(i8 %X, i8 %Y) { 689; CHECK-LABEL: @urem_shl_YX_shl_XX( 690; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]] 691; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]] 692; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 693; CHECK-NEXT: ret i8 [[R]] 694; 695 %BO0 = shl nuw nsw i8 %Y, %X 696 %BO1 = shl nuw nsw i8 %X, %X 697 %r = urem i8 %BO0, %BO1 698 ret i8 %r 699} 700 701define i8 @urem_shl_XX_shl_XZ(i8 %X, i8 %Z) { 702; CHECK-LABEL: @urem_shl_XX_shl_XZ( 703; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]] 704; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]] 705; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 706; CHECK-NEXT: ret i8 [[R]] 707; 708 %BO0 = shl nuw nsw i8 %X, %X 709 %BO1 = shl nuw nsw i8 %X, %Z 710 %r = urem i8 %BO0, %BO1 711 ret i8 %r 712} 713 714define i8 @urem_shl_XY_shl_XX(i8 %X, i8 %Y) { 715; CHECK-LABEL: @urem_shl_XY_shl_XX( 716; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]] 717; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]] 718; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 719; CHECK-NEXT: ret i8 [[R]] 720; 721 %BO0 = shl nuw nsw i8 %X, %Y 722 %BO1 = shl nuw nsw i8 %X, %X 723 %r = urem i8 %BO0, %BO1 724 ret i8 %r 725} 726 727define i8 @urem_mul_XX_shl_ZX(i8 %X, i8 %Z) { 728; CHECK-LABEL: @urem_mul_XX_shl_ZX( 729; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]] 730; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]] 731; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 732; CHECK-NEXT: ret i8 [[R]] 733; 734 %BO0 = mul nuw nsw i8 %X, %X 735 %BO1 = shl nuw nsw i8 %Z, %X 736 %r = urem i8 %BO0, %BO1 737 ret i8 %r 738} 739 740define i8 @urem_mul_YX_shl_XX(i8 %X, i8 %Y) { 741; CHECK-LABEL: @urem_mul_YX_shl_XX( 742; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]] 743; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]] 744; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 745; CHECK-NEXT: ret i8 [[R]] 746; 747 %BO0 = mul nuw nsw i8 %Y, %X 748 %BO1 = shl nuw nsw i8 %X, %X 749 %r = urem i8 %BO0, %BO1 750 ret i8 %r 751} 752 753define i8 @urem_mul_XX_shl_XZ(i8 %X, i8 %Z) { 754; CHECK-LABEL: @urem_mul_XX_shl_XZ( 755; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]] 756; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]] 757; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 758; CHECK-NEXT: ret i8 [[R]] 759; 760 %BO0 = mul nuw nsw i8 %X, %X 761 %BO1 = shl nuw nsw i8 %X, %Z 762 %r = urem i8 %BO0, %BO1 763 ret i8 %r 764} 765 766define i8 @urem_mul_XY_shl_XX(i8 %X, i8 %Y) { 767; CHECK-LABEL: @urem_mul_XY_shl_XX( 768; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]] 769; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]] 770; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 771; CHECK-NEXT: ret i8 [[R]] 772; 773 %BO0 = mul nuw nsw i8 %X, %Y 774 %BO1 = shl nuw nsw i8 %X, %X 775 %r = urem i8 %BO0, %BO1 776 ret i8 %r 777} 778 779define i8 @urem_shl_XX_mul_ZX(i8 %X, i8 %Z) { 780; CHECK-LABEL: @urem_shl_XX_mul_ZX( 781; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]] 782; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]] 783; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 784; CHECK-NEXT: ret i8 [[R]] 785; 786 %BO0 = shl nuw nsw i8 %X, %X 787 %BO1 = mul nuw nsw i8 %Z, %X 788 %r = urem i8 %BO0, %BO1 789 ret i8 %r 790} 791 792define i8 @urem_shl_YX_mul_XX(i8 %X, i8 %Y) { 793; CHECK-LABEL: @urem_shl_YX_mul_XX( 794; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]] 795; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]] 796; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 797; CHECK-NEXT: ret i8 [[R]] 798; 799 %BO0 = shl nuw nsw i8 %Y, %X 800 %BO1 = mul nuw nsw i8 %X, %X 801 %r = urem i8 %BO0, %BO1 802 ret i8 %r 803} 804 805define i8 @urem_shl_XX_mul_XZ(i8 %X, i8 %Z) { 806; CHECK-LABEL: @urem_shl_XX_mul_XZ( 807; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]] 808; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]] 809; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 810; CHECK-NEXT: ret i8 [[R]] 811; 812 %BO0 = shl nuw nsw i8 %X, %X 813 %BO1 = mul nuw nsw i8 %X, %Z 814 %r = urem i8 %BO0, %BO1 815 ret i8 %r 816} 817 818define i8 @urem_shl_XY_mul_XX(i8 %X, i8 %Y) { 819; CHECK-LABEL: @urem_shl_XY_mul_XX( 820; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]] 821; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]] 822; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 823; CHECK-NEXT: ret i8 [[R]] 824; 825 %BO0 = shl nuw nsw i8 %X, %Y 826 %BO1 = mul nuw nsw i8 %X, %X 827 %r = urem i8 %BO0, %BO1 828 ret i8 %r 829} 830 831define i8 @urem_mul_XX_shl_XX(i8 %X) { 832; CHECK-LABEL: @urem_mul_XX_shl_XX( 833; CHECK-NEXT: [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]] 834; CHECK-NEXT: [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]] 835; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 836; CHECK-NEXT: ret i8 [[R]] 837; 838 %BO0 = mul nuw nsw i8 %X, %X 839 %BO1 = shl nuw nsw i8 %X, %X 840 %r = urem i8 %BO0, %BO1 841 ret i8 %r 842} 843 844define i8 @urem_shl_XX_mul_XX(i8 %X) { 845; CHECK-LABEL: @urem_shl_XX_mul_XX( 846; CHECK-NEXT: [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]] 847; CHECK-NEXT: [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]] 848; CHECK-NEXT: [[R:%.*]] = urem i8 [[BO0]], [[BO1]] 849; CHECK-NEXT: ret i8 [[R]] 850; 851 %BO0 = shl nuw nsw i8 %X, %X 852 %BO1 = mul nuw nsw i8 %X, %X 853 %r = urem i8 %BO0, %BO1 854 ret i8 %r 855} 856 857; Negative test: No attribute vscale_range to indicate range 858define i64 @urem_shl_vscale() { 859; CHECK-LABEL: @urem_shl_vscale( 860; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 861; CHECK-NEXT: [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 2 862; CHECK-NEXT: [[REM:%.*]] = urem i64 1024, [[SHIFT]] 863; CHECK-NEXT: ret i64 [[REM]] 864; 865 %vscale = call i64 @llvm.vscale.i64() 866 %shift = shl nuw nsw i64 %vscale, 2 867 %rem = urem i64 1024, %shift 868 ret i64 %rem 869} 870 871define i64 @urem_shl_vscale_range() vscale_range(1,16) { 872; CHECK-LABEL: @urem_shl_vscale_range( 873; CHECK-NEXT: ret i64 0 874; 875 %vscale = call i64 @llvm.vscale.i64() 876 %shift = shl nuw nsw i64 %vscale, 2 877 %rem = urem i64 1024, %shift 878 ret i64 %rem 879} 880 881define i64 @urem_vscale_range() vscale_range(1,16) { 882; CHECK-LABEL: @urem_vscale_range( 883; CHECK-NEXT: ret i64 0 884; 885 %vscale = call i64 @llvm.vscale.i64() 886 %shift = shl nuw nsw i64 %vscale, 6 887 %rem = urem i64 1024, %shift 888 ret i64 %rem 889} 890 891define i64 @urem_shl_vscale_out_of_range() vscale_range(1,16) { 892; CHECK-LABEL: @urem_shl_vscale_out_of_range( 893; CHECK-NEXT: ret i64 1024 894; 895 %vscale = call i64 @llvm.vscale.i64() 896 %shift = shl nuw nsw i64 %vscale, 11 897 %rem = urem i64 1024, %shift 898 ret i64 %rem 899} 900 901; Negative test: The min value 1 << 10 is overlap to 1024 902define i64 @urem_shl_vscale_overlap() vscale_range(1,16) { 903; CHECK-LABEL: @urem_shl_vscale_overlap( 904; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 905; CHECK-NEXT: [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 10 906; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[SHIFT]], 2047 907; CHECK-NEXT: [[REM:%.*]] = and i64 [[TMP1]], 1024 908; CHECK-NEXT: ret i64 [[REM]] 909; 910 %vscale = call i64 @llvm.vscale.i64() 911 %shift = shl nuw nsw i64 %vscale, 10 912 %rem = urem i64 1024, %shift 913 ret i64 %rem 914} 915 916define i64 @and_add_vscale_range_low() vscale_range(1,16) { 917; CHECK-LABEL: @and_add_vscale_range_low( 918; CHECK-NEXT: ret i64 0 919; 920 %vscale = call i64 @llvm.vscale.i64() 921 %shift = shl nuw nsw i64 %vscale, 6 922 %add = add i64 %shift, -1 923 %rem = and i64 1024, %add 924 ret i64 %rem 925} 926 927; TODO: have no bits that may be part of the mask set, 928; but now expect the const is a power of two 929define i64 @and_add_shl_vscale_not_power2() vscale_range(1,16) { 930; CHECK-LABEL: @and_add_shl_vscale_not_power2( 931; CHECK-NEXT: [[VSCALE:%.*]] = call i64 @llvm.vscale.i64() 932; CHECK-NEXT: [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 6 933; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[SHIFT]], 4095 934; CHECK-NEXT: [[REM:%.*]] = and i64 [[ADD]], 3072 935; CHECK-NEXT: ret i64 [[REM]] 936; 937 %vscale = call i64 @llvm.vscale.i64() 938 %shift = shl nuw nsw i64 %vscale, 6 939 %add = add i64 %shift, -1 940 %rem = and i64 3072, %add 941 ret i64 %rem 942} 943 944; Allow for INT_MIN, https://alive2.llvm.org/ce/z/yZ_I2a 945define i32 @and_add_shl_vscale_not_power2_negative() vscale_range(1,16) { 946; CHECK-LABEL: @and_add_shl_vscale_not_power2_negative( 947; CHECK-NEXT: ret i32 0 948; 949 %vscale = call i32 @llvm.vscale.i32() 950 %shift = shl nuw nsw i32 %vscale, 6 951 %add = add i32 %shift, -1 952 %rem = and i32 -2147483648, %add 953 ret i32 %rem 954} 955 956; Negative test: the %sign may be 0, https://alive2.llvm.org/ce/z/WU_j4a 957define i32 @and_add_and (i32 %x) { 958; CHECK-LABEL: @and_add_and( 959; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 24 960; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -2147483648 961; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP2]], -2147483648 962; CHECK-NEXT: ret i32 [[AND]] 963; 964 %x1 = lshr i32 %x, 7 965 %sign = and i32 %x1, 1 ; %sign = (%x >> 7) & 1 966 %add = add i32 %sign, -1 967 %and = and i32 %add, 2147483648 968 ret i32 %and 969} 970 971