1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s 3 4; PR33879 - use shift eflags result when it won't cause stalls 5 6; ashr by constant - use sarl eflags result 7define i32 @ashr_const(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 8; CHECK-LABEL: ashr_const: 9; CHECK: # %bb.0: 10; CHECK-NEXT: movl %edx, %eax 11; CHECK-NEXT: sarl $14, %edi 12; CHECK-NEXT: cmovnel %ecx, %eax 13; CHECK-NEXT: retq 14 %s = ashr i32 %a0, 14 15 %c = icmp eq i32 %s, 0 16 %r = select i1 %c, i32 %a2, i32 %a3 17 ret i32 %r 18} 19 20; lshr by constant - simplify to test 21define i32 @lshr_const(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 22; CHECK-LABEL: lshr_const: 23; CHECK: # %bb.0: 24; CHECK-NEXT: movl %edx, %eax 25; CHECK-NEXT: testl $-16384, %edi # imm = 0xC000 26; CHECK-NEXT: cmovnel %ecx, %eax 27; CHECK-NEXT: retq 28 %s = lshr i32 %a0, 14 29 %c = icmp eq i32 %s, 0 30 %r = select i1 %c, i32 %a2, i32 %a3 31 ret i32 %r 32} 33 34; shl by constant - simplify to test 35define i32 @shl_const(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 36; CHECK-LABEL: shl_const: 37; CHECK: # %bb.0: 38; CHECK-NEXT: movl %edx, %eax 39; CHECK-NEXT: testl $262143, %edi # imm = 0x3FFFF 40; CHECK-NEXT: cmovnel %ecx, %eax 41; CHECK-NEXT: retq 42 %s = shl i32 %a0, 14 43 %c = icmp eq i32 %s, 0 44 %r = select i1 %c, i32 %a2, i32 %a3 45 ret i32 %r 46} 47 48; ashr by constant and using shift result - use sarl eflags result 49define i32 @ashr_const_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 50; CHECK-LABEL: ashr_const_self_select: 51; CHECK: # %bb.0: 52; CHECK-NEXT: movl %edi, %eax 53; CHECK-NEXT: sarl $14, %eax 54; CHECK-NEXT: cmovnel %edx, %eax 55; CHECK-NEXT: retq 56 %s = ashr i32 %a0, 14 57 %c = icmp eq i32 %s, 0 58 %r = select i1 %c, i32 %s, i32 %a2 59 ret i32 %r 60} 61 62; lshr by constant and using shift result - use shrl eflags result 63define i32 @lshr_const_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 64; CHECK-LABEL: lshr_const_self_select: 65; CHECK: # %bb.0: 66; CHECK-NEXT: movl %edi, %eax 67; CHECK-NEXT: shrl $14, %eax 68; CHECK-NEXT: cmovnel %edx, %eax 69; CHECK-NEXT: retq 70 %s = lshr i32 %a0, 14 71 %c = icmp eq i32 %s, 0 72 %r = select i1 %c, i32 %s, i32 %a2 73 ret i32 %r 74} 75 76; lshr by constant and using result - use shll eflags result 77define i32 @shl_const_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 78; CHECK-LABEL: shl_const_self_select: 79; CHECK: # %bb.0: 80; CHECK-NEXT: movl %edi, %eax 81; CHECK-NEXT: shll $14, %eax 82; CHECK-NEXT: cmovnel %edx, %eax 83; CHECK-NEXT: retq 84 %s = shl i32 %a0, 14 85 %c = icmp eq i32 %s, 0 86 %r = select i1 %c, i32 %s, i32 %a2 87 ret i32 %r 88} 89 90; ashr by 1 - use sarl eflags result 91define i32 @ashr_const1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 92; CHECK-LABEL: ashr_const1: 93; CHECK: # %bb.0: 94; CHECK-NEXT: movl %edx, %eax 95; CHECK-NEXT: sarl %edi 96; CHECK-NEXT: cmovnel %ecx, %eax 97; CHECK-NEXT: retq 98 %s = ashr i32 %a0, 1 99 %c = icmp eq i32 %s, 0 100 %r = select i1 %c, i32 %a2, i32 %a3 101 ret i32 %r 102} 103 104; lshr by 1 - simplify to test 105define i32 @lshr_const1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 106; CHECK-LABEL: lshr_const1: 107; CHECK: # %bb.0: 108; CHECK-NEXT: movl %edx, %eax 109; CHECK-NEXT: testl $-2, %edi 110; CHECK-NEXT: cmovnel %ecx, %eax 111; CHECK-NEXT: retq 112 %s = lshr i32 %a0, 1 113 %c = icmp eq i32 %s, 0 114 %r = select i1 %c, i32 %a2, i32 %a3 115 ret i32 %r 116} 117 118; shl by 1 - simplify to test 119define i32 @shl_const1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 120; CHECK-LABEL: shl_const1: 121; CHECK: # %bb.0: 122; CHECK-NEXT: movl %edx, %eax 123; CHECK-NEXT: testl $2147483647, %edi # imm = 0x7FFFFFFF 124; CHECK-NEXT: cmovnel %ecx, %eax 125; CHECK-NEXT: retq 126 %s = shl i32 %a0, 1 127 %c = icmp eq i32 %s, 0 128 %r = select i1 %c, i32 %a2, i32 %a3 129 ret i32 %r 130} 131 132; ashr by 1 and using shift result - use sarl eflags result 133define i32 @ashr_const1_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 134; CHECK-LABEL: ashr_const1_self_select: 135; CHECK: # %bb.0: 136; CHECK-NEXT: movl %edi, %eax 137; CHECK-NEXT: sarl %eax 138; CHECK-NEXT: cmovnel %edx, %eax 139; CHECK-NEXT: retq 140 %s = ashr i32 %a0, 1 141 %c = icmp eq i32 %s, 0 142 %r = select i1 %c, i32 %s, i32 %a2 143 ret i32 %r 144} 145 146; lshr by 1 and using shift result - use shrl eflags result 147define i32 @lshr_const1_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 148; CHECK-LABEL: lshr_const1_self_select: 149; CHECK: # %bb.0: 150; CHECK-NEXT: movl %edi, %eax 151; CHECK-NEXT: shrl %eax 152; CHECK-NEXT: cmovnel %edx, %eax 153; CHECK-NEXT: retq 154 %s = lshr i32 %a0, 1 155 %c = icmp eq i32 %s, 0 156 %r = select i1 %c, i32 %s, i32 %a2 157 ret i32 %r 158} 159 160; lshr by 1 and using result - use addl eflags result 161define i32 @shl_const1_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 162; CHECK-LABEL: shl_const1_self_select: 163; CHECK: # %bb.0: 164; CHECK-NEXT: movl %edi, %eax 165; CHECK-NEXT: addl %edi, %eax 166; CHECK-NEXT: cmovnel %edx, %eax 167; CHECK-NEXT: retq 168 %s = shl i32 %a0, 1 169 %c = icmp eq i32 %s, 0 170 %r = select i1 %c, i32 %s, i32 %a2 171 ret i32 %r 172} 173 174; ashr by variable - use separate test 175define i32 @ashr_var(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 176; CHECK-LABEL: ashr_var: 177; CHECK: # %bb.0: 178; CHECK-NEXT: movl %ecx, %eax 179; CHECK-NEXT: movl %esi, %ecx 180; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 181; CHECK-NEXT: sarl %cl, %edi 182; CHECK-NEXT: testl %edi, %edi 183; CHECK-NEXT: cmovel %edx, %eax 184; CHECK-NEXT: retq 185 %s = ashr i32 %a0, %a1 186 %c = icmp eq i32 %s, 0 187 %r = select i1 %c, i32 %a2, i32 %a3 188 ret i32 %r 189} 190 191; lshr by variable - use separate test 192define i32 @lshr_var(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 193; CHECK-LABEL: lshr_var: 194; CHECK: # %bb.0: 195; CHECK-NEXT: movl %ecx, %eax 196; CHECK-NEXT: movl %esi, %ecx 197; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 198; CHECK-NEXT: shrl %cl, %edi 199; CHECK-NEXT: testl %edi, %edi 200; CHECK-NEXT: cmovel %edx, %eax 201; CHECK-NEXT: retq 202 %s = lshr i32 %a0, %a1 203 %c = icmp eq i32 %s, 0 204 %r = select i1 %c, i32 %a2, i32 %a3 205 ret i32 %r 206} 207 208; shl by variable - use separate test 209define i32 @shl_var(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 210; CHECK-LABEL: shl_var: 211; CHECK: # %bb.0: 212; CHECK-NEXT: movl %ecx, %eax 213; CHECK-NEXT: movl %esi, %ecx 214; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 215; CHECK-NEXT: shll %cl, %edi 216; CHECK-NEXT: testl %edi, %edi 217; CHECK-NEXT: cmovel %edx, %eax 218; CHECK-NEXT: retq 219 %s = shl i32 %a0, %a1 220 %c = icmp eq i32 %s, 0 221 %r = select i1 %c, i32 %a2, i32 %a3 222 ret i32 %r 223} 224 225; ashr by variable and using result - use separate test 226define i32 @ashr_var_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 227; CHECK-LABEL: ashr_var_self_select: 228; CHECK: # %bb.0: 229; CHECK-NEXT: movl %esi, %ecx 230; CHECK-NEXT: movl %edi, %eax 231; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 232; CHECK-NEXT: sarl %cl, %eax 233; CHECK-NEXT: testl %eax, %eax 234; CHECK-NEXT: cmovnel %edx, %eax 235; CHECK-NEXT: retq 236 %s = ashr i32 %a0, %a1 237 %c = icmp eq i32 %s, 0 238 %r = select i1 %c, i32 %s, i32 %a2 239 ret i32 %r 240} 241 242; lshr by variable and using result - use separate test 243define i32 @lshr_var_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 244; CHECK-LABEL: lshr_var_self_select: 245; CHECK: # %bb.0: 246; CHECK-NEXT: movl %esi, %ecx 247; CHECK-NEXT: movl %edi, %eax 248; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 249; CHECK-NEXT: shrl %cl, %eax 250; CHECK-NEXT: testl %eax, %eax 251; CHECK-NEXT: cmovnel %edx, %eax 252; CHECK-NEXT: retq 253 %s = lshr i32 %a0, %a1 254 %c = icmp eq i32 %s, 0 255 %r = select i1 %c, i32 %s, i32 %a2 256 ret i32 %r 257} 258 259; shl by variable and using result - use separate test 260define i32 @shl_var_self_select(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 261; CHECK-LABEL: shl_var_self_select: 262; CHECK: # %bb.0: 263; CHECK-NEXT: movl %esi, %ecx 264; CHECK-NEXT: movl %edi, %eax 265; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 266; CHECK-NEXT: shll %cl, %eax 267; CHECK-NEXT: testl %eax, %eax 268; CHECK-NEXT: cmovnel %edx, %eax 269; CHECK-NEXT: retq 270 %s = shl i32 %a0, %a1 271 %c = icmp eq i32 %s, 0 272 %r = select i1 %c, i32 %s, i32 %a2 273 ret i32 %r 274} 275 276; ashr by non-zero variable - use separate test 277define i32 @ashr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 278; CHECK-LABEL: ashr_var_amt_never_zero: 279; CHECK: # %bb.0: 280; CHECK-NEXT: movl %ecx, %eax 281; CHECK-NEXT: movl %esi, %ecx 282; CHECK-NEXT: orb $1, %cl 283; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 284; CHECK-NEXT: sarl %cl, %edi 285; CHECK-NEXT: testl %edi, %edi 286; CHECK-NEXT: cmovel %edx, %eax 287; CHECK-NEXT: retq 288 %a = or i32 %a1, 1 289 %s = ashr i32 %a0, %a 290 %c = icmp eq i32 %s, 0 291 %r = select i1 %c, i32 %a2, i32 %a3 292 ret i32 %r 293} 294 295; lshr by non-zero variable - use separate test 296define i32 @lshr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 297; CHECK-LABEL: lshr_var_amt_never_zero: 298; CHECK: # %bb.0: 299; CHECK-NEXT: movl %ecx, %eax 300; CHECK-NEXT: movl %esi, %ecx 301; CHECK-NEXT: orb $1, %cl 302; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 303; CHECK-NEXT: shrl %cl, %edi 304; CHECK-NEXT: testl %edi, %edi 305; CHECK-NEXT: cmovel %edx, %eax 306; CHECK-NEXT: retq 307 %a = or i32 %a1, 1 308 %s = lshr i32 %a0, %a 309 %c = icmp eq i32 %s, 0 310 %r = select i1 %c, i32 %a2, i32 %a3 311 ret i32 %r 312} 313 314; shl by non-zero variable - use separate test 315define i32 @shl_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 316; CHECK-LABEL: shl_var_amt_never_zero: 317; CHECK: # %bb.0: 318; CHECK-NEXT: movl %ecx, %eax 319; CHECK-NEXT: movl %esi, %ecx 320; CHECK-NEXT: orb $1, %cl 321; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 322; CHECK-NEXT: shll %cl, %edi 323; CHECK-NEXT: testl %edi, %edi 324; CHECK-NEXT: cmovel %edx, %eax 325; CHECK-NEXT: retq 326 %a = or i32 %a1, 1 327 %s = shl i32 %a0, %a 328 %c = icmp eq i32 %s, 0 329 %r = select i1 %c, i32 %a2, i32 %a3 330 ret i32 %r 331} 332 333; ashr by non-zero variable and using result - use separate test 334define i32 @ashr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 335; CHECK-LABEL: ashr_var_self_select_amt_never_zero: 336; CHECK: # %bb.0: 337; CHECK-NEXT: movl %esi, %ecx 338; CHECK-NEXT: movl %edi, %eax 339; CHECK-NEXT: orb $1, %cl 340; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 341; CHECK-NEXT: shrl %cl, %eax 342; CHECK-NEXT: testl %eax, %eax 343; CHECK-NEXT: cmovnel %edx, %eax 344; CHECK-NEXT: retq 345 %a = or i32 %a1, 1 346 %s = lshr i32 %a0, %a 347 %c = icmp eq i32 %s, 0 348 %r = select i1 %c, i32 %s, i32 %a2 349 ret i32 %r 350} 351 352; lshr by non-zero variable and using result - use separate test 353define i32 @lshr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 354; CHECK-LABEL: lshr_var_self_select_amt_never_zero: 355; CHECK: # %bb.0: 356; CHECK-NEXT: movl %esi, %ecx 357; CHECK-NEXT: movl %edi, %eax 358; CHECK-NEXT: orb $1, %cl 359; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 360; CHECK-NEXT: shrl %cl, %eax 361; CHECK-NEXT: testl %eax, %eax 362; CHECK-NEXT: cmovnel %edx, %eax 363; CHECK-NEXT: retq 364 %a = or i32 %a1, 1 365 %s = lshr i32 %a0, %a 366 %c = icmp eq i32 %s, 0 367 %r = select i1 %c, i32 %s, i32 %a2 368 ret i32 %r 369} 370 371; shl by non-zero variable and using result - use separate test 372define i32 @shl_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) { 373; CHECK-LABEL: shl_var_self_select_amt_never_zero: 374; CHECK: # %bb.0: 375; CHECK-NEXT: movl %esi, %ecx 376; CHECK-NEXT: movl %edi, %eax 377; CHECK-NEXT: orb $1, %cl 378; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx 379; CHECK-NEXT: shrl %cl, %eax 380; CHECK-NEXT: testl %eax, %eax 381; CHECK-NEXT: cmovnel %edx, %eax 382; CHECK-NEXT: retq 383 %a = or i32 %a1, 1 384 %s = lshr i32 %a0, %a 385 %c = icmp eq i32 %s, 0 386 %r = select i1 %c, i32 %s, i32 %a2 387 ret i32 %r 388} 389