1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i32 @ashr_lshr_exact_ashr_only(i32 %x, i32 %y) { 5; CHECK-LABEL: @ashr_lshr_exact_ashr_only( 6; CHECK-NEXT: [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 7; CHECK-NEXT: ret i32 [[CMP12]] 8; 9 %cmp = icmp sgt i32 %x, -1 10 %l = lshr i32 %x, %y 11 %r = ashr exact i32 %x, %y 12 %ret = select i1 %cmp, i32 %l, i32 %r 13 ret i32 %ret 14} 15 16define i32 @ashr_lshr_no_exact(i32 %x, i32 %y) { 17; CHECK-LABEL: @ashr_lshr_no_exact( 18; CHECK-NEXT: [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 19; CHECK-NEXT: ret i32 [[CMP12]] 20; 21 %cmp = icmp sgt i32 %x, -1 22 %l = lshr i32 %x, %y 23 %r = ashr i32 %x, %y 24 %ret = select i1 %cmp, i32 %l, i32 %r 25 ret i32 %ret 26} 27 28define i32 @ashr_lshr_exact_both(i32 %x, i32 %y) { 29; CHECK-LABEL: @ashr_lshr_exact_both( 30; CHECK-NEXT: [[CMP12:%.*]] = ashr exact i32 [[X:%.*]], [[Y:%.*]] 31; CHECK-NEXT: ret i32 [[CMP12]] 32; 33 %cmp = icmp sgt i32 %x, -1 34 %l = lshr exact i32 %x, %y 35 %r = ashr exact i32 %x, %y 36 %ret = select i1 %cmp, i32 %l, i32 %r 37 ret i32 %ret 38} 39 40define i32 @ashr_lshr_exact_lshr_only(i32 %x, i32 %y) { 41; CHECK-LABEL: @ashr_lshr_exact_lshr_only( 42; CHECK-NEXT: [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 43; CHECK-NEXT: ret i32 [[CMP12]] 44; 45 %cmp = icmp sgt i32 %x, -1 46 %l = lshr exact i32 %x, %y 47 %r = ashr i32 %x, %y 48 %ret = select i1 %cmp, i32 %l, i32 %r 49 ret i32 %ret 50} 51 52define i32 @ashr_lshr2(i32 %x, i32 %y) { 53; CHECK-LABEL: @ashr_lshr2( 54; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 55; CHECK-NEXT: ret i32 [[CMP1]] 56; 57 %cmp = icmp sgt i32 %x, 5 58 %l = lshr i32 %x, %y 59 %r = ashr exact i32 %x, %y 60 %ret = select i1 %cmp, i32 %l, i32 %r 61 ret i32 %ret 62} 63 64define i128 @ashr_lshr2_i128(i128 %x, i128 %y) { 65; CHECK-LABEL: @ashr_lshr2_i128( 66; CHECK-NEXT: [[CMP1:%.*]] = ashr i128 [[X:%.*]], [[Y:%.*]] 67; CHECK-NEXT: ret i128 [[CMP1]] 68; 69 %cmp = icmp sgt i128 %x, 5 70 %l = lshr i128 %x, %y 71 %r = ashr exact i128 %x, %y 72 %ret = select i1 %cmp, i128 %l, i128 %r 73 ret i128 %ret 74} 75 76define <2 x i32> @ashr_lshr_splat_vec(<2 x i32> %x, <2 x i32> %y) { 77; CHECK-LABEL: @ashr_lshr_splat_vec( 78; CHECK-NEXT: [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 79; CHECK-NEXT: ret <2 x i32> [[CMP12]] 80; 81 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 82 %l = lshr <2 x i32> %x, %y 83 %r = ashr <2 x i32> %x, %y 84 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 85 ret <2 x i32> %ret 86} 87 88define <2 x i32> @ashr_lshr_splat_vec2(<2 x i32> %x, <2 x i32> %y) { 89; CHECK-LABEL: @ashr_lshr_splat_vec2( 90; CHECK-NEXT: [[CMP12:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]] 91; CHECK-NEXT: ret <2 x i32> [[CMP12]] 92; 93 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 94 %l = lshr exact <2 x i32> %x, %y 95 %r = ashr exact <2 x i32> %x, %y 96 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 97 ret <2 x i32> %ret 98} 99 100define <2 x i32> @ashr_lshr_splat_vec3(<2 x i32> %x, <2 x i32> %y) { 101; CHECK-LABEL: @ashr_lshr_splat_vec3( 102; CHECK-NEXT: [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 103; CHECK-NEXT: ret <2 x i32> [[CMP12]] 104; 105 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 106 %l = lshr exact <2 x i32> %x, %y 107 %r = ashr <2 x i32> %x, %y 108 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 109 ret <2 x i32> %ret 110} 111 112define <2 x i32> @ashr_lshr_splat_vec4(<2 x i32> %x, <2 x i32> %y) { 113; CHECK-LABEL: @ashr_lshr_splat_vec4( 114; CHECK-NEXT: [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 115; CHECK-NEXT: ret <2 x i32> [[CMP12]] 116; 117 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 118 %l = lshr <2 x i32> %x, %y 119 %r = ashr exact <2 x i32> %x, %y 120 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 121 ret <2 x i32> %ret 122} 123 124define <2 x i32> @ashr_lshr_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) { 125; CHECK-LABEL: @ashr_lshr_nonsplat_vec( 126; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 127; CHECK-NEXT: ret <2 x i32> [[CMP1]] 128; 129 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 1> 130 %l = lshr <2 x i32> %x, %y 131 %r = ashr <2 x i32> %x, %y 132 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 133 ret <2 x i32> %ret 134} 135 136define <2 x i32> @ashr_lshr_nonsplat_vec2(<2 x i32> %x, <2 x i32> %y) { 137; CHECK-LABEL: @ashr_lshr_nonsplat_vec2( 138; CHECK-NEXT: [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]] 139; CHECK-NEXT: ret <2 x i32> [[CMP1]] 140; 141 %cmp = icmp sgt <2 x i32> %x, <i32 2, i32 4> 142 %l = lshr exact <2 x i32> %x, %y 143 %r = ashr exact <2 x i32> %x, %y 144 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 145 ret <2 x i32> %ret 146} 147 148define <2 x i32> @ashr_lshr_nonsplat_vec3(<2 x i32> %x, <2 x i32> %y) { 149; CHECK-LABEL: @ashr_lshr_nonsplat_vec3( 150; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 151; CHECK-NEXT: ret <2 x i32> [[CMP1]] 152; 153 %cmp = icmp sgt <2 x i32> %x, <i32 5, i32 6> 154 %l = lshr exact <2 x i32> %x, %y 155 %r = ashr <2 x i32> %x, %y 156 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 157 ret <2 x i32> %ret 158} 159 160define <2 x i32> @ashr_lshr_nonsplat_vec4(<2 x i32> %x, <2 x i32> %y) { 161; CHECK-LABEL: @ashr_lshr_nonsplat_vec4( 162; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 163; CHECK-NEXT: ret <2 x i32> [[CMP1]] 164; 165 %cmp = icmp sgt <2 x i32> %x, <i32 8, i32 7> 166 %l = lshr <2 x i32> %x, %y 167 %r = ashr exact <2 x i32> %x, %y 168 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 169 ret <2 x i32> %ret 170} 171 172define i32 @ashr_lshr_cst(i32 %x, i32 %y) { 173; CHECK-LABEL: @ashr_lshr_cst( 174; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8 175; CHECK-NEXT: ret i32 [[CMP1]] 176; 177 %cmp = icmp slt i32 %x, 1 178 %l = lshr i32 %x, 8 179 %r = ashr exact i32 %x, 8 180 %ret = select i1 %cmp, i32 %r, i32 %l 181 ret i32 %ret 182} 183 184define i32 @ashr_lshr_cst2(i32 %x, i32 %y) { 185; CHECK-LABEL: @ashr_lshr_cst2( 186; CHECK-NEXT: [[CMP12:%.*]] = ashr i32 [[X:%.*]], 8 187; CHECK-NEXT: ret i32 [[CMP12]] 188; 189 %cmp = icmp sgt i32 %x, -1 190 %l = lshr i32 %x, 8 191 %r = ashr exact i32 %x, 8 192 %ret = select i1 %cmp, i32 %l, i32 %r 193 ret i32 %ret 194} 195 196define i32 @ashr_lshr_inv(i32 %x, i32 %y) { 197; CHECK-LABEL: @ashr_lshr_inv( 198; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 199; CHECK-NEXT: ret i32 [[CMP1]] 200; 201 %cmp = icmp slt i32 %x, 1 202 %l = lshr i32 %x, %y 203 %r = ashr exact i32 %x, %y 204 %ret = select i1 %cmp, i32 %r, i32 %l 205 ret i32 %ret 206} 207 208define i32 @ashr_lshr_inv2(i32 %x, i32 %y) { 209; CHECK-LABEL: @ashr_lshr_inv2( 210; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 211; CHECK-NEXT: ret i32 [[CMP1]] 212; 213 %cmp = icmp slt i32 %x, 7 214 %l = lshr i32 %x, %y 215 %r = ashr exact i32 %x, %y 216 %ret = select i1 %cmp, i32 %r, i32 %l 217 ret i32 %ret 218} 219 220define <2 x i32> @ashr_lshr_inv_splat_vec(<2 x i32> %x, <2 x i32> %y) { 221; CHECK-LABEL: @ashr_lshr_inv_splat_vec( 222; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 223; CHECK-NEXT: ret <2 x i32> [[CMP1]] 224; 225 %cmp = icmp slt <2 x i32> %x, <i32 1, i32 1> 226 %l = lshr <2 x i32> %x, %y 227 %r = ashr exact <2 x i32> %x, %y 228 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 229 ret <2 x i32> %ret 230} 231 232define <2 x i32> @ashr_lshr_inv_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) { 233; CHECK-LABEL: @ashr_lshr_inv_nonsplat_vec( 234; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 235; CHECK-NEXT: ret <2 x i32> [[CMP1]] 236; 237 %cmp = icmp slt <2 x i32> %x, <i32 4, i32 5> 238 %l = lshr <2 x i32> %x, %y 239 %r = ashr exact <2 x i32> %x, %y 240 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 241 ret <2 x i32> %ret 242} 243 244define <2 x i32> @ashr_lshr_vec_poison(<2 x i32> %x, <2 x i32> %y) { 245; CHECK-LABEL: @ashr_lshr_vec_poison( 246; CHECK-NEXT: [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 247; CHECK-NEXT: ret <2 x i32> [[CMP12]] 248; 249 %cmp = icmp sgt <2 x i32> %x, <i32 poison, i32 -1> 250 %l = lshr <2 x i32> %x, %y 251 %r = ashr exact <2 x i32> %x, %y 252 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 253 ret <2 x i32> %ret 254} 255 256define <2 x i32> @ashr_lshr_vec_poison2(<2 x i32> %x, <2 x i32> %y) { 257; CHECK-LABEL: @ashr_lshr_vec_poison2( 258; CHECK-NEXT: [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]] 259; CHECK-NEXT: ret <2 x i32> [[CMP1]] 260; 261 %cmp = icmp slt <2 x i32> %x, <i32 1, i32 poison> 262 %l = lshr exact <2 x i32> %x, %y 263 %r = ashr exact <2 x i32> %x, %y 264 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 265 ret <2 x i32> %ret 266} 267 268; Negative tests 269 270define i32 @ashr_lshr_wrong_cst(i32 %x, i32 %y) { 271; CHECK-LABEL: @ashr_lshr_wrong_cst( 272; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2 273; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 274; CHECK-NEXT: [[R:%.*]] = ashr exact i32 [[X]], [[Y]] 275; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 276; CHECK-NEXT: ret i32 [[RET]] 277; 278 %cmp = icmp sgt i32 %x, -2 279 %l = lshr i32 %x, %y 280 %r = ashr exact i32 %x, %y 281 %ret = select i1 %cmp, i32 %l, i32 %r 282 ret i32 %ret 283} 284 285define i32 @ashr_lshr_wrong_cst2(i32 %x, i32 %y) { 286; CHECK-LABEL: @ashr_lshr_wrong_cst2( 287; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], -1 288; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 289; CHECK-NEXT: [[R:%.*]] = ashr exact i32 [[X]], [[Y]] 290; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]] 291; CHECK-NEXT: ret i32 [[RET]] 292; 293 %cmp = icmp slt i32 %x, -1 294 %l = lshr i32 %x, %y 295 %r = ashr exact i32 %x, %y 296 %ret = select i1 %cmp, i32 %r, i32 %l 297 ret i32 %ret 298} 299 300define i32 @ashr_lshr_wrong_cond(i32 %x, i32 %y) { 301; CHECK-LABEL: @ashr_lshr_wrong_cond( 302; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2 303; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 304; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 305; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 306; CHECK-NEXT: ret i32 [[RET]] 307; 308 %cmp = icmp sge i32 %x, -1 309 %l = lshr i32 %x, %y 310 %r = ashr i32 %x, %y 311 %ret = select i1 %cmp, i32 %l, i32 %r 312 ret i32 %ret 313} 314 315define i32 @ashr_lshr_shift_wrong_pred(i32 %x, i32 %y, i32 %z) { 316; CHECK-LABEL: @ashr_lshr_shift_wrong_pred( 317; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 318; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 319; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 320; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 321; CHECK-NEXT: ret i32 [[RET]] 322; 323 %cmp = icmp sle i32 %x, 0 324 %l = lshr i32 %x, %y 325 %r = ashr i32 %x, %y 326 %ret = select i1 %cmp, i32 %l, i32 %r 327 ret i32 %ret 328} 329 330define i32 @ashr_lshr_shift_wrong_pred2(i32 %x, i32 %y, i32 %z) { 331; CHECK-LABEL: @ashr_lshr_shift_wrong_pred2( 332; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 333; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 334; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[Z:%.*]], 0 335; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]] 336; CHECK-NEXT: ret i32 [[RET]] 337; 338 %cmp = icmp sge i32 %z, 0 339 %l = lshr i32 %x, %y 340 %r = ashr i32 %x, %y 341 %ret = select i1 %cmp, i32 %l, i32 %r 342 ret i32 %ret 343} 344 345define i32 @ashr_lshr_wrong_operands(i32 %x, i32 %y) { 346; CHECK-LABEL: @ashr_lshr_wrong_operands( 347; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 348; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 349; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 0 350; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i32 [[L]], i32 [[R]] 351; CHECK-NEXT: ret i32 [[RET]] 352; 353 %cmp = icmp sge i32 %x, 0 354 %l = lshr i32 %x, %y 355 %r = ashr i32 %x, %y 356 %ret = select i1 %cmp, i32 %r, i32 %l 357 ret i32 %ret 358} 359 360define i32 @ashr_lshr_no_ashr(i32 %x, i32 %y) { 361; CHECK-LABEL: @ashr_lshr_no_ashr( 362; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 363; CHECK-NEXT: [[R:%.*]] = xor i32 [[X]], [[Y]] 364; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 0 365; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]] 366; CHECK-NEXT: ret i32 [[RET]] 367; 368 %cmp = icmp sge i32 %x, 0 369 %l = lshr i32 %x, %y 370 %r = xor i32 %x, %y 371 %ret = select i1 %cmp, i32 %l, i32 %r 372 ret i32 %ret 373} 374 375define i32 @ashr_lshr_shift_amt_mismatch(i32 %x, i32 %y, i32 %z) { 376; CHECK-LABEL: @ashr_lshr_shift_amt_mismatch( 377; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 378; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Z:%.*]] 379; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 0 380; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]] 381; CHECK-NEXT: ret i32 [[RET]] 382; 383 %cmp = icmp sge i32 %x, 0 384 %l = lshr i32 %x, %y 385 %r = ashr i32 %x, %z 386 %ret = select i1 %cmp, i32 %l, i32 %r 387 ret i32 %ret 388} 389 390define i32 @ashr_lshr_shift_base_mismatch(i32 %x, i32 %y, i32 %z) { 391; CHECK-LABEL: @ashr_lshr_shift_base_mismatch( 392; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 393; CHECK-NEXT: [[R:%.*]] = ashr i32 [[Z:%.*]], [[Y]] 394; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 0 395; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]] 396; CHECK-NEXT: ret i32 [[RET]] 397; 398 %cmp = icmp sge i32 %x, 0 399 %l = lshr i32 %x, %y 400 %r = ashr i32 %z, %y 401 %ret = select i1 %cmp, i32 %l, i32 %r 402 ret i32 %ret 403} 404 405define i32 @ashr_lshr_no_lshr(i32 %x, i32 %y) { 406; CHECK-LABEL: @ashr_lshr_no_lshr( 407; CHECK-NEXT: [[L:%.*]] = add i32 [[X:%.*]], [[Y:%.*]] 408; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 409; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X]], 0 410; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]] 411; CHECK-NEXT: ret i32 [[RET]] 412; 413 %cmp = icmp sge i32 %x, 0 414 %l = add i32 %x, %y 415 %r = ashr i32 %x, %y 416 %ret = select i1 %cmp, i32 %l, i32 %r 417 ret i32 %ret 418} 419 420define <2 x i32> @ashr_lshr_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) { 421; CHECK-LABEL: @ashr_lshr_vec_wrong_pred( 422; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], splat (i32 1) 423; CHECK-NEXT: [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 424; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]] 425; CHECK-NEXT: [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[L]], <2 x i32> [[R]] 426; CHECK-NEXT: ret <2 x i32> [[RET]] 427; 428 %cmp = icmp sle <2 x i32> %x, zeroinitializer 429 %l = lshr <2 x i32> %x, %y 430 %r = ashr <2 x i32> %x, %y 431 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 432 ret <2 x i32> %ret 433} 434 435define <2 x i32> @ashr_lshr_inv_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) { 436; CHECK-LABEL: @ashr_lshr_inv_vec_wrong_pred( 437; CHECK-NEXT: [[L:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]] 438; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]] 439; CHECK-NEXT: [[CMP1:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer 440; CHECK-NEXT: [[RET:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[L]], <2 x i32> [[R]] 441; CHECK-NEXT: ret <2 x i32> [[RET]] 442; 443 %cmp = icmp sge <2 x i32> %x, zeroinitializer 444 %l = lshr <2 x i32> %x, %y 445 %r = ashr <2 x i32> %x, %y 446 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 447 ret <2 x i32> %ret 448} 449 450define i32 @lshr_sub_nsw(i32 %x, i32 %y) { 451; CHECK-LABEL: @lshr_sub_nsw( 452; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 453; CHECK-NEXT: [[SHR:%.*]] = zext i1 [[TMP1]] to i32 454; CHECK-NEXT: ret i32 [[SHR]] 455; 456 %sub = sub nsw i32 %x, %y 457 %shr = lshr i32 %sub, 31 458 ret i32 %shr 459} 460 461; negative test - must shift sign-bit 462 463define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) { 464; CHECK-LABEL: @lshr_sub_wrong_amount( 465; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 466; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 30 467; CHECK-NEXT: ret i32 [[SHR]] 468; 469 %sub = sub nsw i32 %x, %y 470 %shr = lshr i32 %sub, 30 471 ret i32 %shr 472} 473 474; negative test - must have nsw 475 476define i32 @lshr_sub(i32 %x, i32 %y) { 477; CHECK-LABEL: @lshr_sub( 478; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 479; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 31 480; CHECK-NEXT: ret i32 [[SHR]] 481; 482 %sub = sub i32 %x, %y 483 %shr = lshr i32 %sub, 31 484 ret i32 %shr 485} 486 487; negative test - one-use 488 489define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, ptr %p) { 490; CHECK-LABEL: @lshr_sub_nsw_extra_use( 491; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 492; CHECK-NEXT: store i32 [[SUB]], ptr [[P:%.*]], align 4 493; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 31 494; CHECK-NEXT: ret i32 [[SHR]] 495; 496 %sub = sub nsw i32 %x, %y 497 store i32 %sub, ptr %p 498 %shr = lshr i32 %sub, 31 499 ret i32 %shr 500} 501 502define <3 x i42> @lshr_sub_nsw_splat(<3 x i42> %x, <3 x i42> %y) { 503; CHECK-LABEL: @lshr_sub_nsw_splat( 504; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i42> [[X:%.*]], [[Y:%.*]] 505; CHECK-NEXT: [[SHR:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i42> 506; CHECK-NEXT: ret <3 x i42> [[SHR]] 507; 508 %sub = sub nsw <3 x i42> %x, %y 509 %shr = lshr <3 x i42> %sub, <i42 41, i42 41, i42 41> 510 ret <3 x i42> %shr 511} 512 513define <3 x i42> @lshr_sub_nsw_splat_poison(<3 x i42> %x, <3 x i42> %y) { 514; CHECK-LABEL: @lshr_sub_nsw_splat_poison( 515; CHECK-NEXT: [[SUB:%.*]] = sub nsw <3 x i42> [[X:%.*]], [[Y:%.*]] 516; CHECK-NEXT: [[SHR:%.*]] = lshr <3 x i42> [[SUB]], <i42 41, i42 poison, i42 41> 517; CHECK-NEXT: ret <3 x i42> [[SHR]] 518; 519 %sub = sub nsw <3 x i42> %x, %y 520 %shr = lshr <3 x i42> %sub, <i42 41, i42 poison, i42 41> 521 ret <3 x i42> %shr 522} 523 524define i17 @ashr_sub_nsw(i17 %x, i17 %y) { 525; CHECK-LABEL: @ashr_sub_nsw( 526; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i17 [[X:%.*]], [[Y:%.*]] 527; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP1]] to i17 528; CHECK-NEXT: ret i17 [[SHR]] 529; 530 %sub = sub nsw i17 %x, %y 531 %shr = ashr i17 %sub, 16 532 ret i17 %shr 533} 534 535; negative test - must shift sign-bit 536 537define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) { 538; CHECK-LABEL: @ashr_sub_wrong_amount( 539; CHECK-NEXT: [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]] 540; CHECK-NEXT: [[SHR:%.*]] = ashr i17 [[SUB]], 15 541; CHECK-NEXT: ret i17 [[SHR]] 542; 543 %sub = sub nsw i17 %x, %y 544 %shr = ashr i17 %sub, 15 545 ret i17 %shr 546} 547 548; negative test - must have nsw 549 550define i32 @ashr_sub(i32 %x, i32 %y) { 551; CHECK-LABEL: @ashr_sub( 552; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 553; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[SUB]], 31 554; CHECK-NEXT: ret i32 [[SHR]] 555; 556 %sub = sub i32 %x, %y 557 %shr = ashr i32 %sub, 31 558 ret i32 %shr 559} 560 561; negative test - one-use 562 563define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, ptr %p) { 564; CHECK-LABEL: @ashr_sub_nsw_extra_use( 565; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 566; CHECK-NEXT: store i32 [[SUB]], ptr [[P:%.*]], align 4 567; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[SUB]], 31 568; CHECK-NEXT: ret i32 [[SHR]] 569; 570 %sub = sub nsw i32 %x, %y 571 store i32 %sub, ptr %p 572 %shr = ashr i32 %sub, 31 573 ret i32 %shr 574} 575 576define <3 x i43> @ashr_sub_nsw_splat(<3 x i43> %x, <3 x i43> %y) { 577; CHECK-LABEL: @ashr_sub_nsw_splat( 578; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i43> [[X:%.*]], [[Y:%.*]] 579; CHECK-NEXT: [[SHR:%.*]] = sext <3 x i1> [[TMP1]] to <3 x i43> 580; CHECK-NEXT: ret <3 x i43> [[SHR]] 581; 582 %sub = sub nsw <3 x i43> %x, %y 583 %shr = ashr <3 x i43> %sub, <i43 42, i43 42, i43 42> 584 ret <3 x i43> %shr 585} 586 587define <3 x i43> @ashr_sub_nsw_splat_poison(<3 x i43> %x, <3 x i43> %y) { 588; CHECK-LABEL: @ashr_sub_nsw_splat_poison( 589; CHECK-NEXT: [[SUB:%.*]] = sub nsw <3 x i43> [[X:%.*]], [[Y:%.*]] 590; CHECK-NEXT: [[SHR:%.*]] = ashr <3 x i43> [[SUB]], <i43 42, i43 poison, i43 42> 591; CHECK-NEXT: ret <3 x i43> [[SHR]] 592; 593 %sub = sub nsw <3 x i43> %x, %y 594 %shr = ashr <3 x i43> %sub, <i43 42, i43 poison, i43 42> 595 ret <3 x i43> %shr 596} 597 598define i8 @ashr_known_pos_exact(i8 %x, i8 %y) { 599; CHECK-LABEL: @ashr_known_pos_exact( 600; CHECK-NEXT: [[P:%.*]] = and i8 [[X:%.*]], 127 601; CHECK-NEXT: [[R:%.*]] = lshr exact i8 [[P]], [[Y:%.*]] 602; CHECK-NEXT: ret i8 [[R]] 603; 604 %p = and i8 %x, 127 605 %r = ashr exact i8 %p, %y 606 ret i8 %r 607} 608 609define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) { 610; CHECK-LABEL: @ashr_known_pos_exact_vec( 611; CHECK-NEXT: [[P:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[X]] 612; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i8> [[P]], [[Y:%.*]] 613; CHECK-NEXT: ret <2 x i8> [[R]] 614; 615 %p = mul nsw <2 x i8> %x, %x 616 %r = ashr exact <2 x i8> %p, %y 617 ret <2 x i8> %r 618} 619 620define i32 @lshr_mul_times_3_div_2(i32 %0) { 621; CHECK-LABEL: @lshr_mul_times_3_div_2( 622; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1 623; CHECK-NEXT: [[LSHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]] 624; CHECK-NEXT: ret i32 [[LSHR]] 625; 626 %mul = mul nsw nuw i32 %0, 3 627 %lshr = lshr i32 %mul, 1 628 ret i32 %lshr 629} 630 631define i32 @lshr_mul_times_3_div_2_exact(i32 %x) { 632; CHECK-LABEL: @lshr_mul_times_3_div_2_exact( 633; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1 634; CHECK-NEXT: [[LSHR:%.*]] = add nsw i32 [[X]], [[TMP1]] 635; CHECK-NEXT: ret i32 [[LSHR]] 636; 637 %mul = mul nsw i32 %x, 3 638 %lshr = lshr exact i32 %mul, 1 639 ret i32 %lshr 640} 641 642; Negative test 643 644define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) { 645; CHECK-LABEL: @lshr_mul_times_3_div_2_no_flags( 646; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3 647; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[MUL]], 1 648; CHECK-NEXT: ret i32 [[LSHR]] 649; 650 %mul = mul i32 %0, 3 651 %lshr = lshr i32 %mul, 1 652 ret i32 %lshr 653} 654 655; Negative test 656 657define i32 @mul_times_3_div_2_multiuse_lshr(i32 %x) { 658; CHECK-LABEL: @mul_times_3_div_2_multiuse_lshr( 659; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 3 660; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[MUL]], 1 661; CHECK-NEXT: call void @use(i32 [[MUL]]) 662; CHECK-NEXT: ret i32 [[RES]] 663; 664 %mul = mul nuw i32 %x, 3 665 %res = lshr i32 %mul, 1 666 call void @use(i32 %mul) 667 ret i32 %res 668} 669 670define i32 @lshr_mul_times_3_div_2_exact_2(i32 %x) { 671; CHECK-LABEL: @lshr_mul_times_3_div_2_exact_2( 672; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1 673; CHECK-NEXT: [[LSHR:%.*]] = add nuw i32 [[X]], [[TMP1]] 674; CHECK-NEXT: ret i32 [[LSHR]] 675; 676 %mul = mul nuw i32 %x, 3 677 %lshr = lshr exact i32 %mul, 1 678 ret i32 %lshr 679} 680 681define i32 @lshr_mul_times_5_div_4(i32 %0) { 682; CHECK-LABEL: @lshr_mul_times_5_div_4( 683; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2 684; CHECK-NEXT: [[LSHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]] 685; CHECK-NEXT: ret i32 [[LSHR]] 686; 687 %mul = mul nsw nuw i32 %0, 5 688 %lshr = lshr i32 %mul, 2 689 ret i32 %lshr 690} 691 692define i32 @lshr_mul_times_5_div_4_exact(i32 %x) { 693; CHECK-LABEL: @lshr_mul_times_5_div_4_exact( 694; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2 695; CHECK-NEXT: [[LSHR:%.*]] = add nsw i32 [[X]], [[TMP1]] 696; CHECK-NEXT: ret i32 [[LSHR]] 697; 698 %mul = mul nsw i32 %x, 5 699 %lshr = lshr exact i32 %mul, 2 700 ret i32 %lshr 701} 702 703; Negative test 704 705define i32 @lshr_mul_times_5_div_4_no_flags(i32 %0) { 706; CHECK-LABEL: @lshr_mul_times_5_div_4_no_flags( 707; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5 708; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[MUL]], 2 709; CHECK-NEXT: ret i32 [[LSHR]] 710; 711 %mul = mul i32 %0, 5 712 %lshr = lshr i32 %mul, 2 713 ret i32 %lshr 714} 715 716; Negative test 717 718define i32 @mul_times_5_div_4_multiuse_lshr(i32 %x) { 719; CHECK-LABEL: @mul_times_5_div_4_multiuse_lshr( 720; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 5 721; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[MUL]], 2 722; CHECK-NEXT: call void @use(i32 [[MUL]]) 723; CHECK-NEXT: ret i32 [[RES]] 724; 725 %mul = mul nuw i32 %x, 5 726 %res = lshr i32 %mul, 2 727 call void @use(i32 %mul) 728 ret i32 %res 729} 730 731define i32 @lshr_mul_times_5_div_4_exact_2(i32 %x) { 732; CHECK-LABEL: @lshr_mul_times_5_div_4_exact_2( 733; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2 734; CHECK-NEXT: [[LSHR:%.*]] = add nuw i32 [[X]], [[TMP1]] 735; CHECK-NEXT: ret i32 [[LSHR]] 736; 737 %mul = mul nuw i32 %x, 5 738 %lshr = lshr exact i32 %mul, 2 739 ret i32 %lshr 740} 741 742define i32 @ashr_mul_times_3_div_2(i32 %0) { 743; CHECK-LABEL: @ashr_mul_times_3_div_2( 744; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1 745; CHECK-NEXT: [[ASHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]] 746; CHECK-NEXT: ret i32 [[ASHR]] 747; 748 %mul = mul nuw nsw i32 %0, 3 749 %ashr = ashr i32 %mul, 1 750 ret i32 %ashr 751} 752 753define i32 @ashr_mul_times_3_div_2_exact(i32 %x) { 754; CHECK-LABEL: @ashr_mul_times_3_div_2_exact( 755; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1 756; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]] 757; CHECK-NEXT: ret i32 [[ASHR]] 758; 759 %mul = mul nsw i32 %x, 3 760 %ashr = ashr exact i32 %mul, 1 761 ret i32 %ashr 762} 763 764; Negative test 765 766define i32 @ashr_mul_times_3_div_2_no_flags(i32 %0) { 767; CHECK-LABEL: @ashr_mul_times_3_div_2_no_flags( 768; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3 769; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[MUL]], 1 770; CHECK-NEXT: ret i32 [[ASHR]] 771; 772 %mul = mul i32 %0, 3 773 %ashr = ashr i32 %mul, 1 774 ret i32 %ashr 775} 776 777; Negative test 778 779define i32 @ashr_mul_times_3_div_2_no_nsw(i32 %0) { 780; CHECK-LABEL: @ashr_mul_times_3_div_2_no_nsw( 781; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[TMP0:%.*]], 3 782; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[MUL]], 1 783; CHECK-NEXT: ret i32 [[ASHR]] 784; 785 %mul = mul nuw i32 %0, 3 786 %ashr = ashr i32 %mul, 1 787 ret i32 %ashr 788} 789 790; Negative test 791 792define i32 @mul_times_3_div_2_multiuse_ashr(i32 %x) { 793; CHECK-LABEL: @mul_times_3_div_2_multiuse_ashr( 794; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 3 795; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[MUL]], 1 796; CHECK-NEXT: call void @use(i32 [[MUL]]) 797; CHECK-NEXT: ret i32 [[RES]] 798; 799 %mul = mul nsw i32 %x, 3 800 %res = ashr i32 %mul, 1 801 call void @use(i32 %mul) 802 ret i32 %res 803} 804 805define i32 @ashr_mul_times_3_div_2_exact_2(i32 %x) { 806; CHECK-LABEL: @ashr_mul_times_3_div_2_exact_2( 807; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1 808; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]] 809; CHECK-NEXT: ret i32 [[ASHR]] 810; 811 %mul = mul nsw i32 %x, 3 812 %ashr = ashr exact i32 %mul, 1 813 ret i32 %ashr 814} 815 816define i32 @ashr_mul_times_5_div_4(i32 %0) { 817; CHECK-LABEL: @ashr_mul_times_5_div_4( 818; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2 819; CHECK-NEXT: [[ASHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]] 820; CHECK-NEXT: ret i32 [[ASHR]] 821; 822 %mul = mul nuw nsw i32 %0, 5 823 %ashr = ashr i32 %mul, 2 824 ret i32 %ashr 825} 826 827define i32 @ashr_mul_times_5_div_4_exact(i32 %x) { 828; CHECK-LABEL: @ashr_mul_times_5_div_4_exact( 829; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2 830; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]] 831; CHECK-NEXT: ret i32 [[ASHR]] 832; 833 %mul = mul nsw i32 %x, 5 834 %ashr = ashr exact i32 %mul, 2 835 ret i32 %ashr 836} 837 838; Negative test 839 840define i32 @ashr_mul_times_5_div_4_no_flags(i32 %0) { 841; CHECK-LABEL: @ashr_mul_times_5_div_4_no_flags( 842; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5 843; CHECK-NEXT: [[ASHR:%.*]] = ashr i32 [[MUL]], 2 844; CHECK-NEXT: ret i32 [[ASHR]] 845; 846 %mul = mul i32 %0, 5 847 %ashr = ashr i32 %mul, 2 848 ret i32 %ashr 849} 850 851; Negative test 852 853define i32 @mul_times_5_div_4_multiuse_ashr(i32 %x) { 854; CHECK-LABEL: @mul_times_5_div_4_multiuse_ashr( 855; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 5 856; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[MUL]], 2 857; CHECK-NEXT: call void @use(i32 [[MUL]]) 858; CHECK-NEXT: ret i32 [[RES]] 859; 860 %mul = mul nsw i32 %x, 5 861 %res = ashr i32 %mul, 2 862 call void @use(i32 %mul) 863 ret i32 %res 864} 865 866define i32 @ashr_mul_times_5_div_4_exact_2(i32 %x) { 867; CHECK-LABEL: @ashr_mul_times_5_div_4_exact_2( 868; CHECK-NEXT: [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2 869; CHECK-NEXT: [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]] 870; CHECK-NEXT: ret i32 [[ASHR]] 871; 872 %mul = mul nsw i32 %x, 5 873 %ashr = ashr exact i32 %mul, 2 874 ret i32 %ashr 875} 876 877 878define i32 @lsb_mask_sign_zext(i32 %x) { 879; CHECK-LABEL: @lsb_mask_sign_zext( 880; CHECK-NEXT: entry: 881; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0 882; CHECK-NEXT: [[SHR:%.*]] = zext i1 [[TMP0]] to i32 883; CHECK-NEXT: ret i32 [[SHR]] 884; 885entry: 886 %sub = add i32 %x, -1 887 %not = xor i32 %x, -1 888 %and = and i32 %sub, %not 889 %shr = lshr i32 %and, 31 890 ret i32 %shr 891} 892 893define i32 @lsb_mask_sign_zext_commuted(i32 %x) { 894; CHECK-LABEL: @lsb_mask_sign_zext_commuted( 895; CHECK-NEXT: entry: 896; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0 897; CHECK-NEXT: [[SHR:%.*]] = zext i1 [[TMP0]] to i32 898; CHECK-NEXT: ret i32 [[SHR]] 899; 900entry: 901 %sub = add i32 %x, -1 902 %not = xor i32 %x, -1 903 %and = and i32 %not, %sub 904 %shr = lshr i32 %and, 31 905 ret i32 %shr 906} 907 908; Negative tests 909 910define i32 @lsb_mask_sign_zext_wrong_cst1(i32 %x) { 911; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst1( 912; CHECK-NEXT: entry: 913; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -2 914; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[X]], -1 915; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[NOT]] 916; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[AND]], 31 917; CHECK-NEXT: ret i32 [[SHR]] 918; 919entry: 920 %sub = add i32 %x, -2 921 %not = xor i32 %x, -1 922 %and = and i32 %sub, %not 923 %shr = lshr i32 %and, 31 924 ret i32 %shr 925} 926 927define i32 @lsb_mask_sign_zext_wrong_cst2(i32 %x) { 928; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst2( 929; CHECK-NEXT: entry: 930; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -1 931; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[X]] 932; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[AND]], 31 933; CHECK-NEXT: ret i32 [[SHR]] 934; 935entry: 936 %sub = add i32 %x, -1 937 %not = xor i32 %x, 2 938 %and = and i32 %sub, %not 939 %shr = lshr i32 %and, 31 940 ret i32 %shr 941} 942 943define i32 @lsb_mask_sign_zext_wrong_cst3(i32 %x) { 944; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst3( 945; CHECK-NEXT: entry: 946; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -1 947; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[X]], -1 948; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[NOT]] 949; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[AND]], 30 950; CHECK-NEXT: ret i32 [[SHR]] 951; 952entry: 953 %sub = add i32 %x, -1 954 %not = xor i32 %x, -1 955 %and = and i32 %sub, %not 956 %shr = lshr i32 %and, 30 957 ret i32 %shr 958} 959 960define i32 @lsb_mask_sign_zext_multiuse(i32 %x) { 961; CHECK-LABEL: @lsb_mask_sign_zext_multiuse( 962; CHECK-NEXT: entry: 963; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -1 964; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[X]], -1 965; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[NOT]] 966; CHECK-NEXT: call void @use(i32 [[AND]]) 967; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[AND]], 31 968; CHECK-NEXT: ret i32 [[SHR]] 969; 970entry: 971 %sub = add i32 %x, -1 972 %not = xor i32 %x, -1 973 %and = and i32 %sub, %not 974 call void @use(i32 %and) 975 %shr = lshr i32 %and, 31 976 ret i32 %shr 977} 978 979define i32 @lsb_mask_sign_sext(i32 %x) { 980; CHECK-LABEL: @lsb_mask_sign_sext( 981; CHECK-NEXT: entry: 982; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0 983; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP0]] to i32 984; CHECK-NEXT: ret i32 [[SHR]] 985; 986entry: 987 %sub = add i32 %x, -1 988 %not = xor i32 %x, -1 989 %and = and i32 %sub, %not 990 %shr = ashr i32 %and, 31 991 ret i32 %shr 992} 993 994define i32 @lsb_mask_sign_sext_commuted(i32 %x) { 995; CHECK-LABEL: @lsb_mask_sign_sext_commuted( 996; CHECK-NEXT: entry: 997; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0 998; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP0]] to i32 999; CHECK-NEXT: ret i32 [[SHR]] 1000; 1001entry: 1002 %sub = add i32 %x, -1 1003 %not = xor i32 %x, -1 1004 %and = and i32 %not, %sub 1005 %shr = ashr i32 %and, 31 1006 ret i32 %shr 1007} 1008 1009; Negative tests 1010 1011define i32 @lsb_mask_sign_sext_wrong_cst1(i32 %x) { 1012; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst1( 1013; CHECK-NEXT: entry: 1014; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -2 1015; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[X]], -1 1016; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[NOT]] 1017; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[AND]], 31 1018; CHECK-NEXT: ret i32 [[SHR]] 1019; 1020entry: 1021 %sub = add i32 %x, -2 1022 %not = xor i32 %x, -1 1023 %and = and i32 %sub, %not 1024 %shr = ashr i32 %and, 31 1025 ret i32 %shr 1026} 1027 1028define i32 @lsb_mask_sign_sext_wrong_cst2(i32 %x) { 1029; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst2( 1030; CHECK-NEXT: entry: 1031; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -1 1032; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[X]] 1033; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[AND]], 31 1034; CHECK-NEXT: ret i32 [[SHR]] 1035; 1036entry: 1037 %sub = add i32 %x, -1 1038 %not = xor i32 %x, 2 1039 %and = and i32 %sub, %not 1040 %shr = ashr i32 %and, 31 1041 ret i32 %shr 1042} 1043 1044define i32 @lsb_mask_sign_sext_wrong_cst3(i32 %x) { 1045; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst3( 1046; CHECK-NEXT: entry: 1047; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -1 1048; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[X]], -1 1049; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[NOT]] 1050; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[AND]], 30 1051; CHECK-NEXT: ret i32 [[SHR]] 1052; 1053entry: 1054 %sub = add i32 %x, -1 1055 %not = xor i32 %x, -1 1056 %and = and i32 %sub, %not 1057 %shr = ashr i32 %and, 30 1058 ret i32 %shr 1059} 1060 1061define i32 @lsb_mask_sign_sext_multiuse(i32 %x) { 1062; CHECK-LABEL: @lsb_mask_sign_sext_multiuse( 1063; CHECK-NEXT: entry: 1064; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X:%.*]], -1 1065; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[X]], -1 1066; CHECK-NEXT: [[AND:%.*]] = and i32 [[SUB]], [[NOT]] 1067; CHECK-NEXT: call void @use(i32 [[AND]]) 1068; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[AND]], 31 1069; CHECK-NEXT: ret i32 [[SHR]] 1070; 1071entry: 1072 %sub = add i32 %x, -1 1073 %not = xor i32 %x, -1 1074 %and = and i32 %sub, %not 1075 call void @use(i32 %and) 1076 %shr = ashr i32 %and, 31 1077 ret i32 %shr 1078} 1079 1080declare void @use(i32) 1081