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