1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 7; CHECK-NEXT: ret i32 [[CMP1]] 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: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 19; CHECK-NEXT: ret i32 [[CMP1]] 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: [[CMP1:%.*]] = ashr exact i32 [[X:%.*]], [[Y:%.*]] 31; CHECK-NEXT: ret i32 [[CMP1]] 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: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 43; CHECK-NEXT: ret i32 [[CMP1]] 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 <2 x i32> @ashr_lshr_splat_vec(<2 x i32> %x, <2 x i32> %y) { 65; CHECK-LABEL: @ashr_lshr_splat_vec( 66; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 67; CHECK-NEXT: ret <2 x i32> [[CMP1]] 68; 69 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 70 %l = lshr <2 x i32> %x, %y 71 %r = ashr <2 x i32> %x, %y 72 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 73 ret <2 x i32> %ret 74} 75 76define <2 x i32> @ashr_lshr_splat_vec2(<2 x i32> %x, <2 x i32> %y) { 77; CHECK-LABEL: @ashr_lshr_splat_vec2( 78; CHECK-NEXT: [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]] 79; CHECK-NEXT: ret <2 x i32> [[CMP1]] 80; 81 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 82 %l = lshr exact <2 x i32> %x, %y 83 %r = ashr exact <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_vec3(<2 x i32> %x, <2 x i32> %y) { 89; CHECK-LABEL: @ashr_lshr_splat_vec3( 90; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 91; CHECK-NEXT: ret <2 x i32> [[CMP1]] 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 <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_vec4(<2 x i32> %x, <2 x i32> %y) { 101; CHECK-LABEL: @ashr_lshr_splat_vec4( 102; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 103; CHECK-NEXT: ret <2 x i32> [[CMP1]] 104; 105 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 106 %l = lshr <2 x i32> %x, %y 107 %r = ashr exact <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_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) { 113; CHECK-LABEL: @ashr_lshr_nonsplat_vec( 114; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 115; CHECK-NEXT: ret <2 x i32> [[CMP1]] 116; 117 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 1> 118 %l = lshr <2 x i32> %x, %y 119 %r = ashr <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_vec2(<2 x i32> %x, <2 x i32> %y) { 125; CHECK-LABEL: @ashr_lshr_nonsplat_vec2( 126; CHECK-NEXT: [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]] 127; CHECK-NEXT: ret <2 x i32> [[CMP1]] 128; 129 %cmp = icmp sgt <2 x i32> %x, <i32 2, i32 4> 130 %l = lshr exact <2 x i32> %x, %y 131 %r = ashr exact <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_vec3(<2 x i32> %x, <2 x i32> %y) { 137; CHECK-LABEL: @ashr_lshr_nonsplat_vec3( 138; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 139; CHECK-NEXT: ret <2 x i32> [[CMP1]] 140; 141 %cmp = icmp sgt <2 x i32> %x, <i32 5, i32 6> 142 %l = lshr exact <2 x i32> %x, %y 143 %r = ashr <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_vec4(<2 x i32> %x, <2 x i32> %y) { 149; CHECK-LABEL: @ashr_lshr_nonsplat_vec4( 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 8, i32 7> 154 %l = lshr <2 x i32> %x, %y 155 %r = ashr exact <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 i32 @ashr_lshr_cst(i32 %x, i32 %y) { 161; CHECK-LABEL: @ashr_lshr_cst( 162; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8 163; CHECK-NEXT: ret i32 [[CMP1]] 164; 165 %cmp = icmp slt i32 %x, 1 166 %l = lshr i32 %x, 8 167 %r = ashr exact i32 %x, 8 168 %ret = select i1 %cmp, i32 %r, i32 %l 169 ret i32 %ret 170} 171 172define i32 @ashr_lshr_cst2(i32 %x, i32 %y) { 173; CHECK-LABEL: @ashr_lshr_cst2( 174; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8 175; CHECK-NEXT: ret i32 [[CMP1]] 176; 177 %cmp = icmp sgt i32 %x, -1 178 %l = lshr i32 %x, 8 179 %r = ashr exact i32 %x, 8 180 %ret = select i1 %cmp, i32 %l, i32 %r 181 ret i32 %ret 182} 183 184define i32 @ashr_lshr_inv(i32 %x, i32 %y) { 185; CHECK-LABEL: @ashr_lshr_inv( 186; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 187; CHECK-NEXT: ret i32 [[CMP1]] 188; 189 %cmp = icmp slt i32 %x, 1 190 %l = lshr i32 %x, %y 191 %r = ashr exact i32 %x, %y 192 %ret = select i1 %cmp, i32 %r, i32 %l 193 ret i32 %ret 194} 195 196define i32 @ashr_lshr_inv2(i32 %x, i32 %y) { 197; CHECK-LABEL: @ashr_lshr_inv2( 198; CHECK-NEXT: [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]] 199; CHECK-NEXT: ret i32 [[CMP1]] 200; 201 %cmp = icmp slt i32 %x, 7 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 <2 x i32> @ashr_lshr_inv_splat_vec(<2 x i32> %x, <2 x i32> %y) { 209; CHECK-LABEL: @ashr_lshr_inv_splat_vec( 210; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 211; CHECK-NEXT: ret <2 x i32> [[CMP1]] 212; 213 %cmp = icmp slt <2 x i32> %x, <i32 1, i32 1> 214 %l = lshr <2 x i32> %x, %y 215 %r = ashr exact <2 x i32> %x, %y 216 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 217 ret <2 x i32> %ret 218} 219 220define <2 x i32> @ashr_lshr_inv_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) { 221; CHECK-LABEL: @ashr_lshr_inv_nonsplat_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 4, i32 5> 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_vec_undef(<2 x i32> %x, <2 x i32> %y) { 233; CHECK-LABEL: @ashr_lshr_vec_undef( 234; CHECK-NEXT: [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]] 235; CHECK-NEXT: ret <2 x i32> [[CMP1]] 236; 237 %cmp = icmp sgt <2 x i32> %x, <i32 undef, i32 -1> 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> %l, <2 x i32> %r 241 ret <2 x i32> %ret 242} 243 244define <2 x i32> @ashr_lshr_vec_undef2(<2 x i32> %x, <2 x i32> %y) { 245; CHECK-LABEL: @ashr_lshr_vec_undef2( 246; CHECK-NEXT: [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]] 247; CHECK-NEXT: ret <2 x i32> [[CMP1]] 248; 249 %cmp = icmp slt <2 x i32> %x, <i32 1, i32 undef> 250 %l = lshr exact <2 x i32> %x, %y 251 %r = ashr exact <2 x i32> %x, %y 252 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 253 ret <2 x i32> %ret 254} 255 256; Negative tests 257 258define i32 @ashr_lshr_wrong_cst(i32 %x, i32 %y) { 259; CHECK-LABEL: @ashr_lshr_wrong_cst( 260; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2 261; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 262; CHECK-NEXT: [[R:%.*]] = ashr exact i32 [[X]], [[Y]] 263; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 264; CHECK-NEXT: ret i32 [[RET]] 265; 266 %cmp = icmp sgt i32 %x, -2 267 %l = lshr i32 %x, %y 268 %r = ashr exact i32 %x, %y 269 %ret = select i1 %cmp, i32 %l, i32 %r 270 ret i32 %ret 271} 272 273define i32 @ashr_lshr_wrong_cst2(i32 %x, i32 %y) { 274; CHECK-LABEL: @ashr_lshr_wrong_cst2( 275; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], -1 276; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 277; CHECK-NEXT: [[R:%.*]] = ashr exact i32 [[X]], [[Y]] 278; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]] 279; CHECK-NEXT: ret i32 [[RET]] 280; 281 %cmp = icmp slt i32 %x, -1 282 %l = lshr i32 %x, %y 283 %r = ashr exact i32 %x, %y 284 %ret = select i1 %cmp, i32 %r, i32 %l 285 ret i32 %ret 286} 287 288define i32 @ashr_lshr_wrong_cond(i32 %x, i32 %y) { 289; CHECK-LABEL: @ashr_lshr_wrong_cond( 290; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2 291; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 292; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 293; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 294; CHECK-NEXT: ret i32 [[RET]] 295; 296 %cmp = icmp sge i32 %x, -1 297 %l = lshr i32 %x, %y 298 %r = ashr i32 %x, %y 299 %ret = select i1 %cmp, i32 %l, i32 %r 300 ret i32 %ret 301} 302 303define i32 @ashr_lshr_shift_wrong_pred(i32 %x, i32 %y, i32 %z) { 304; CHECK-LABEL: @ashr_lshr_shift_wrong_pred( 305; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 306; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 307; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 308; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 309; CHECK-NEXT: ret i32 [[RET]] 310; 311 %cmp = icmp sle i32 %x, 0 312 %l = lshr i32 %x, %y 313 %r = ashr i32 %x, %y 314 %ret = select i1 %cmp, i32 %l, i32 %r 315 ret i32 %ret 316} 317 318define i32 @ashr_lshr_shift_wrong_pred2(i32 %x, i32 %y, i32 %z) { 319; CHECK-LABEL: @ashr_lshr_shift_wrong_pred2( 320; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[Z:%.*]], -1 321; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]] 322; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 323; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 324; CHECK-NEXT: ret i32 [[RET]] 325; 326 %cmp = icmp sge i32 %z, 0 327 %l = lshr i32 %x, %y 328 %r = ashr i32 %x, %y 329 %ret = select i1 %cmp, i32 %l, i32 %r 330 ret i32 %ret 331} 332 333define i32 @ashr_lshr_wrong_operands(i32 %x, i32 %y) { 334; CHECK-LABEL: @ashr_lshr_wrong_operands( 335; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 336; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 337; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 338; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]] 339; CHECK-NEXT: ret i32 [[RET]] 340; 341 %cmp = icmp sge i32 %x, 0 342 %l = lshr i32 %x, %y 343 %r = ashr i32 %x, %y 344 %ret = select i1 %cmp, i32 %r, i32 %l 345 ret i32 %ret 346} 347 348define i32 @ashr_lshr_no_ashr(i32 %x, i32 %y) { 349; CHECK-LABEL: @ashr_lshr_no_ashr( 350; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 351; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 352; CHECK-NEXT: [[R:%.*]] = xor i32 [[X]], [[Y]] 353; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 354; CHECK-NEXT: ret i32 [[RET]] 355; 356 %cmp = icmp sge i32 %x, 0 357 %l = lshr i32 %x, %y 358 %r = xor i32 %x, %y 359 %ret = select i1 %cmp, i32 %l, i32 %r 360 ret i32 %ret 361} 362 363define i32 @ashr_lshr_shift_amt_mismatch(i32 %x, i32 %y, i32 %z) { 364; CHECK-LABEL: @ashr_lshr_shift_amt_mismatch( 365; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 366; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 367; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Z:%.*]] 368; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 369; CHECK-NEXT: ret i32 [[RET]] 370; 371 %cmp = icmp sge i32 %x, 0 372 %l = lshr i32 %x, %y 373 %r = ashr i32 %x, %z 374 %ret = select i1 %cmp, i32 %l, i32 %r 375 ret i32 %ret 376} 377 378define i32 @ashr_lshr_shift_base_mismatch(i32 %x, i32 %y, i32 %z) { 379; CHECK-LABEL: @ashr_lshr_shift_base_mismatch( 380; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 381; CHECK-NEXT: [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]] 382; CHECK-NEXT: [[R:%.*]] = ashr i32 [[Z:%.*]], [[Y]] 383; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 384; CHECK-NEXT: ret i32 [[RET]] 385; 386 %cmp = icmp sge i32 %x, 0 387 %l = lshr i32 %x, %y 388 %r = ashr i32 %z, %y 389 %ret = select i1 %cmp, i32 %l, i32 %r 390 ret i32 %ret 391} 392 393define i32 @ashr_lshr_no_lshr(i32 %x, i32 %y) { 394; CHECK-LABEL: @ashr_lshr_no_lshr( 395; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 396; CHECK-NEXT: [[L:%.*]] = add i32 [[X]], [[Y:%.*]] 397; CHECK-NEXT: [[R:%.*]] = ashr i32 [[X]], [[Y]] 398; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]] 399; CHECK-NEXT: ret i32 [[RET]] 400; 401 %cmp = icmp sge i32 %x, 0 402 %l = add i32 %x, %y 403 %r = ashr i32 %x, %y 404 %ret = select i1 %cmp, i32 %l, i32 %r 405 ret i32 %ret 406} 407 408define <2 x i32> @ashr_lshr_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) { 409; CHECK-LABEL: @ashr_lshr_vec_wrong_pred( 410; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 1, i32 1> 411; CHECK-NEXT: [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 412; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]] 413; CHECK-NEXT: [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[L]], <2 x i32> [[R]] 414; CHECK-NEXT: ret <2 x i32> [[RET]] 415; 416 %cmp = icmp sle <2 x i32> %x, zeroinitializer 417 %l = lshr <2 x i32> %x, %y 418 %r = ashr <2 x i32> %x, %y 419 %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r 420 ret <2 x i32> %ret 421} 422 423define <2 x i32> @ashr_lshr_inv_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) { 424; CHECK-LABEL: @ashr_lshr_inv_vec_wrong_pred( 425; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1> 426; CHECK-NEXT: [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]] 427; CHECK-NEXT: [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]] 428; CHECK-NEXT: [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[R]], <2 x i32> [[L]] 429; CHECK-NEXT: ret <2 x i32> [[RET]] 430; 431 %cmp = icmp sge <2 x i32> %x, zeroinitializer 432 %l = lshr <2 x i32> %x, %y 433 %r = ashr <2 x i32> %x, %y 434 %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l 435 ret <2 x i32> %ret 436} 437 438define i32 @lshr_sub_nsw(i32 %x, i32 %y) { 439; CHECK-LABEL: @lshr_sub_nsw( 440; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 441; CHECK-NEXT: [[SHR:%.*]] = zext i1 [[TMP1]] to i32 442; CHECK-NEXT: ret i32 [[SHR]] 443; 444 %sub = sub nsw i32 %x, %y 445 %shr = lshr i32 %sub, 31 446 ret i32 %shr 447} 448 449; negative test - must shift sign-bit 450 451define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) { 452; CHECK-LABEL: @lshr_sub_wrong_amount( 453; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 454; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 30 455; CHECK-NEXT: ret i32 [[SHR]] 456; 457 %sub = sub nsw i32 %x, %y 458 %shr = lshr i32 %sub, 30 459 ret i32 %shr 460} 461 462; negative test - must have nsw 463 464define i32 @lshr_sub(i32 %x, i32 %y) { 465; CHECK-LABEL: @lshr_sub( 466; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 467; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 31 468; CHECK-NEXT: ret i32 [[SHR]] 469; 470 %sub = sub i32 %x, %y 471 %shr = lshr i32 %sub, 31 472 ret i32 %shr 473} 474 475; negative test - one-use 476 477define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) { 478; CHECK-LABEL: @lshr_sub_nsw_extra_use( 479; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 480; CHECK-NEXT: store i32 [[SUB]], i32* [[P:%.*]], align 4 481; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 31 482; CHECK-NEXT: ret i32 [[SHR]] 483; 484 %sub = sub nsw i32 %x, %y 485 store i32 %sub, i32* %p 486 %shr = lshr i32 %sub, 31 487 ret i32 %shr 488} 489 490define <3 x i42> @lshr_sub_nsw_splat(<3 x i42> %x, <3 x i42> %y) { 491; CHECK-LABEL: @lshr_sub_nsw_splat( 492; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i42> [[X:%.*]], [[Y:%.*]] 493; CHECK-NEXT: [[SHR:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i42> 494; CHECK-NEXT: ret <3 x i42> [[SHR]] 495; 496 %sub = sub nsw <3 x i42> %x, %y 497 %shr = lshr <3 x i42> %sub, <i42 41, i42 41, i42 41> 498 ret <3 x i42> %shr 499} 500 501define <3 x i42> @lshr_sub_nsw_splat_undef(<3 x i42> %x, <3 x i42> %y) { 502; CHECK-LABEL: @lshr_sub_nsw_splat_undef( 503; CHECK-NEXT: [[SUB:%.*]] = sub nsw <3 x i42> [[X:%.*]], [[Y:%.*]] 504; CHECK-NEXT: [[SHR:%.*]] = lshr <3 x i42> [[SUB]], <i42 41, i42 undef, i42 41> 505; CHECK-NEXT: ret <3 x i42> [[SHR]] 506; 507 %sub = sub nsw <3 x i42> %x, %y 508 %shr = lshr <3 x i42> %sub, <i42 41, i42 undef, i42 41> 509 ret <3 x i42> %shr 510} 511 512define i17 @ashr_sub_nsw(i17 %x, i17 %y) { 513; CHECK-LABEL: @ashr_sub_nsw( 514; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i17 [[X:%.*]], [[Y:%.*]] 515; CHECK-NEXT: [[SHR:%.*]] = sext i1 [[TMP1]] to i17 516; CHECK-NEXT: ret i17 [[SHR]] 517; 518 %sub = sub nsw i17 %x, %y 519 %shr = ashr i17 %sub, 16 520 ret i17 %shr 521} 522 523; negative test - must shift sign-bit 524 525define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) { 526; CHECK-LABEL: @ashr_sub_wrong_amount( 527; CHECK-NEXT: [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]] 528; CHECK-NEXT: [[SHR:%.*]] = ashr i17 [[SUB]], 15 529; CHECK-NEXT: ret i17 [[SHR]] 530; 531 %sub = sub nsw i17 %x, %y 532 %shr = ashr i17 %sub, 15 533 ret i17 %shr 534} 535 536; negative test - must have nsw 537 538define i32 @ashr_sub(i32 %x, i32 %y) { 539; CHECK-LABEL: @ashr_sub( 540; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 541; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[SUB]], 31 542; CHECK-NEXT: ret i32 [[SHR]] 543; 544 %sub = sub i32 %x, %y 545 %shr = ashr i32 %sub, 31 546 ret i32 %shr 547} 548 549; negative test - one-use 550 551define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) { 552; CHECK-LABEL: @ashr_sub_nsw_extra_use( 553; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 554; CHECK-NEXT: store i32 [[SUB]], i32* [[P:%.*]], align 4 555; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[SUB]], 31 556; CHECK-NEXT: ret i32 [[SHR]] 557; 558 %sub = sub nsw i32 %x, %y 559 store i32 %sub, i32* %p 560 %shr = ashr i32 %sub, 31 561 ret i32 %shr 562} 563 564define <3 x i43> @ashr_sub_nsw_splat(<3 x i43> %x, <3 x i43> %y) { 565; CHECK-LABEL: @ashr_sub_nsw_splat( 566; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <3 x i43> [[X:%.*]], [[Y:%.*]] 567; CHECK-NEXT: [[SHR:%.*]] = sext <3 x i1> [[TMP1]] to <3 x i43> 568; CHECK-NEXT: ret <3 x i43> [[SHR]] 569; 570 %sub = sub nsw <3 x i43> %x, %y 571 %shr = ashr <3 x i43> %sub, <i43 42, i43 42, i43 42> 572 ret <3 x i43> %shr 573} 574 575define <3 x i43> @ashr_sub_nsw_splat_undef(<3 x i43> %x, <3 x i43> %y) { 576; CHECK-LABEL: @ashr_sub_nsw_splat_undef( 577; CHECK-NEXT: [[SUB:%.*]] = sub nsw <3 x i43> [[X:%.*]], [[Y:%.*]] 578; CHECK-NEXT: [[SHR:%.*]] = ashr <3 x i43> [[SUB]], <i43 42, i43 undef, i43 42> 579; CHECK-NEXT: ret <3 x i43> [[SHR]] 580; 581 %sub = sub nsw <3 x i43> %x, %y 582 %shr = ashr <3 x i43> %sub, <i43 42, i43 undef, i43 42> 583 ret <3 x i43> %shr 584} 585