1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i32 @sdiv_sext_big_divisor(i8 %x) { 5; CHECK-LABEL: @sdiv_sext_big_divisor( 6; CHECK-NEXT: ret i32 0 7; 8 %conv = sext i8 %x to i32 9 %div = sdiv i32 %conv, 129 10 ret i32 %div 11} 12 13define i32 @not_sdiv_sext_big_divisor(i8 %x) { 14; CHECK-LABEL: @not_sdiv_sext_big_divisor( 15; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 16; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 128 17; CHECK-NEXT: ret i32 [[DIV]] 18; 19 %conv = sext i8 %x to i32 20 %div = sdiv i32 %conv, 128 21 ret i32 %div 22} 23 24define i32 @sdiv_sext_small_divisor(i8 %x) { 25; CHECK-LABEL: @sdiv_sext_small_divisor( 26; CHECK-NEXT: ret i32 0 27; 28 %conv = sext i8 %x to i32 29 %div = sdiv i32 %conv, -129 30 ret i32 %div 31} 32 33define i32 @not_sdiv_sext_small_divisor(i8 %x) { 34; CHECK-LABEL: @not_sdiv_sext_small_divisor( 35; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 36; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -128 37; CHECK-NEXT: ret i32 [[DIV]] 38; 39 %conv = sext i8 %x to i32 40 %div = sdiv i32 %conv, -128 41 ret i32 %div 42} 43 44define i32 @sdiv_zext_big_divisor(i8 %x) { 45; CHECK-LABEL: @sdiv_zext_big_divisor( 46; CHECK-NEXT: ret i32 0 47; 48 %conv = zext i8 %x to i32 49 %div = sdiv i32 %conv, 256 50 ret i32 %div 51} 52 53define i32 @not_sdiv_zext_big_divisor(i8 %x) { 54; CHECK-LABEL: @not_sdiv_zext_big_divisor( 55; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 56; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 255 57; CHECK-NEXT: ret i32 [[DIV]] 58; 59 %conv = zext i8 %x to i32 60 %div = sdiv i32 %conv, 255 61 ret i32 %div 62} 63 64define i32 @sdiv_zext_small_divisor(i8 %x) { 65; CHECK-LABEL: @sdiv_zext_small_divisor( 66; CHECK-NEXT: ret i32 0 67; 68 %conv = zext i8 %x to i32 69 %div = sdiv i32 %conv, -256 70 ret i32 %div 71} 72 73define i32 @not_sdiv_zext_small_divisor(i8 %x) { 74; CHECK-LABEL: @not_sdiv_zext_small_divisor( 75; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 76; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -255 77; CHECK-NEXT: ret i32 [[DIV]] 78; 79 %conv = zext i8 %x to i32 80 %div = sdiv i32 %conv, -255 81 ret i32 %div 82} 83 84define i32 @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { 85; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits( 86; CHECK-NEXT: ret i32 0 87; 88 %and = and i32 %x, 253 89 %div = sdiv i32 %and, 254 90 ret i32 %div 91} 92 93define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { 94; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits( 95; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 253 96; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[AND]], 253 97; CHECK-NEXT: ret i32 [[DIV]] 98; 99 %and = and i32 %x, 253 100 %div = sdiv i32 %and, 253 101 ret i32 %div 102} 103 104define i32 @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { 105; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits( 106; CHECK-NEXT: ret i32 0 107; 108 %and = and i32 %x, 253 109 %div = sdiv i32 %and, -254 110 ret i32 %div 111} 112 113define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { 114; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits( 115; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 253 116; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[AND]], -253 117; CHECK-NEXT: ret i32 [[DIV]] 118; 119 %and = and i32 %x, 253 120 %div = sdiv i32 %and, -253 121 ret i32 %div 122} 123 124define i32 @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { 125; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_set_bits( 126; CHECK-NEXT: ret i32 0 127; 128 %or = or i32 %x, -253 129 %div = sdiv i32 %or, 254 130 ret i32 %div 131} 132 133define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { 134; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits( 135; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -253 136; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], 253 137; CHECK-NEXT: ret i32 [[DIV]] 138; 139 %or = or i32 %x, -253 140 %div = sdiv i32 %or, 253 141 ret i32 %div 142} 143 144define i32 @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { 145; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_set_bits( 146; CHECK-NEXT: ret i32 0 147; 148 %or = or i32 %x, -253 149 %div = sdiv i32 %or, -254 150 ret i32 %div 151} 152 153define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { 154; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits( 155; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -253 156; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], -253 157; CHECK-NEXT: ret i32 [[DIV]] 158; 159 %or = or i32 %x, -253 160 %div = sdiv i32 %or, -253 161 ret i32 %div 162} 163 164define i32 @srem_sext_big_divisor(i8 %x) { 165; CHECK-LABEL: @srem_sext_big_divisor( 166; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 167; CHECK-NEXT: ret i32 [[CONV]] 168; 169 %conv = sext i8 %x to i32 170 %rem = srem i32 %conv, 129 171 ret i32 %rem 172} 173 174define i32 @not_srem_sext_big_divisor(i8 %x) { 175; CHECK-LABEL: @not_srem_sext_big_divisor( 176; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 177; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], 128 178; CHECK-NEXT: ret i32 [[REM]] 179; 180 %conv = sext i8 %x to i32 181 %rem = srem i32 %conv, 128 182 ret i32 %rem 183} 184 185define i32 @srem_sext_small_divisor(i8 %x) { 186; CHECK-LABEL: @srem_sext_small_divisor( 187; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 188; CHECK-NEXT: ret i32 [[CONV]] 189; 190 %conv = sext i8 %x to i32 191 %rem = srem i32 %conv, -129 192 ret i32 %rem 193} 194 195define i32 @not_srem_sext_small_divisor(i8 %x) { 196; CHECK-LABEL: @not_srem_sext_small_divisor( 197; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[X:%.*]] to i32 198; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], -128 199; CHECK-NEXT: ret i32 [[REM]] 200; 201 %conv = sext i8 %x to i32 202 %rem = srem i32 %conv, -128 203 ret i32 %rem 204} 205 206define i32 @srem_zext_big_divisor(i8 %x) { 207; CHECK-LABEL: @srem_zext_big_divisor( 208; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 209; CHECK-NEXT: ret i32 [[CONV]] 210; 211 %conv = zext i8 %x to i32 212 %rem = srem i32 %conv, 256 213 ret i32 %rem 214} 215 216define i32 @not_srem_zext_big_divisor(i8 %x) { 217; CHECK-LABEL: @not_srem_zext_big_divisor( 218; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 219; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], 255 220; CHECK-NEXT: ret i32 [[REM]] 221; 222 %conv = zext i8 %x to i32 223 %rem = srem i32 %conv, 255 224 ret i32 %rem 225} 226 227define i32 @srem_zext_small_divisor(i8 %x) { 228; CHECK-LABEL: @srem_zext_small_divisor( 229; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 230; CHECK-NEXT: ret i32 [[CONV]] 231; 232 %conv = zext i8 %x to i32 233 %rem = srem i32 %conv, -256 234 ret i32 %rem 235} 236 237define i32 @not_srem_zext_small_divisor(i8 %x) { 238; CHECK-LABEL: @not_srem_zext_small_divisor( 239; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[X:%.*]] to i32 240; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], -255 241; CHECK-NEXT: ret i32 [[REM]] 242; 243 %conv = zext i8 %x to i32 244 %rem = srem i32 %conv, -255 245 ret i32 %rem 246} 247 248define i32 @srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { 249; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_clear_bits( 250; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 253 251; CHECK-NEXT: ret i32 [[AND]] 252; 253 %and = and i32 %x, 253 254 %rem = srem i32 %and, 254 255 ret i32 %rem 256} 257 258define i32 @not_srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { 259; CHECK-LABEL: @not_srem_dividend_known_smaller_than_pos_divisor_clear_bits( 260; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 253 261; CHECK-NEXT: [[REM:%.*]] = srem i32 [[AND]], 253 262; CHECK-NEXT: ret i32 [[REM]] 263; 264 %and = and i32 %x, 253 265 %rem = srem i32 %and, 253 266 ret i32 %rem 267} 268 269define i32 @srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { 270; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_clear_bits( 271; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 253 272; CHECK-NEXT: ret i32 [[AND]] 273; 274 %and = and i32 %x, 253 275 %rem = srem i32 %and, -254 276 ret i32 %rem 277} 278 279define i32 @not_srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { 280; CHECK-LABEL: @not_srem_dividend_known_smaller_than_neg_divisor_clear_bits( 281; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 253 282; CHECK-NEXT: [[REM:%.*]] = srem i32 [[AND]], -253 283; CHECK-NEXT: ret i32 [[REM]] 284; 285 %and = and i32 %x, 253 286 %rem = srem i32 %and, -253 287 ret i32 %rem 288} 289 290define i32 @srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { 291; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_set_bits( 292; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -253 293; CHECK-NEXT: ret i32 [[OR]] 294; 295 %or = or i32 %x, -253 296 %rem = srem i32 %or, 254 297 ret i32 %rem 298} 299 300define i32 @not_srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { 301; CHECK-LABEL: @not_srem_dividend_known_smaller_than_pos_divisor_set_bits( 302; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -253 303; CHECK-NEXT: [[REM:%.*]] = srem i32 [[OR]], 253 304; CHECK-NEXT: ret i32 [[REM]] 305; 306 %or = or i32 %x, -253 307 %rem = srem i32 %or, 253 308 ret i32 %rem 309} 310 311define i32 @srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { 312; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_set_bits( 313; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -253 314; CHECK-NEXT: ret i32 [[OR]] 315; 316 %or = or i32 %x, -253 317 %rem = srem i32 %or, -254 318 ret i32 %rem 319} 320 321define i32 @not_srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { 322; CHECK-LABEL: @not_srem_dividend_known_smaller_than_neg_divisor_set_bits( 323; CHECK-NEXT: [[OR:%.*]] = or i32 [[X:%.*]], -253 324; CHECK-NEXT: [[REM:%.*]] = srem i32 [[OR]], -253 325; CHECK-NEXT: ret i32 [[REM]] 326; 327 %or = or i32 %x, -253 328 %rem = srem i32 %or, -253 329 ret i32 %rem 330} 331 332; Make sure that we're handling the minimum signed constant correctly - can't fold this. 333 334define i16 @sdiv_min_dividend(i8 %x) { 335; CHECK-LABEL: @sdiv_min_dividend( 336; CHECK-NEXT: [[Z:%.*]] = zext i8 [[X:%.*]] to i16 337; CHECK-NEXT: [[D:%.*]] = sdiv i16 -32768, [[Z]] 338; CHECK-NEXT: ret i16 [[D]] 339; 340 %z = zext i8 %x to i16 341 %d = sdiv i16 -32768, %z 342 ret i16 %d 343} 344 345; If the quotient is known to not be -32768, then this can fold. 346 347define i16 @sdiv_min_divisor(i8 %x) { 348; CHECK-LABEL: @sdiv_min_divisor( 349; CHECK-NEXT: ret i16 0 350; 351 %z = zext i8 %x to i16 352 %d = sdiv i16 %z, -32768 353 ret i16 %d 354} 355 356