1 ; RUN: opt < %s -instsimplify -S | FileCheck %s 2 3 define 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 12 define 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 23 define 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 32 define 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 43 define 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 52 define 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 63 define 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 72 define 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 83 define 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 92 define 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 103 define 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 112 define 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 123 define 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 132 define 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 143 define 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 152 define 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 163 define 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 173 define 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 184 define 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 194 define 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 205 define 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 215 define 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 226 define 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 236 define 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 247 define 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 257 define 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 268 define 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 278 define 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 289 define 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 299 define 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 310 define 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 320 define 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 333 define 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 346 define 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