Skip to content

Commit e94fc17

Browse files
committed
[X86] Changed so test instruction is removed only when targeting min size.
1 parent 808c771 commit e94fc17

File tree

3 files changed

+170
-22
lines changed

3 files changed

+170
-22
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23634,8 +23634,10 @@ static SDValue EmitTest(SDValue Op, X86::CondCode X86CC, const SDLoc &dl,
2363423634
if (isa<ConstantSDNode>(Amt))
2363523635
break;
2363623636

23637-
// Check we can make this optimization
23638-
if (ArithOp->getFlags().hasNoZero() || DAG.isKnownNeverZero(Amt)) {
23637+
// If optimising for size and can guarantee the shift amt is never zero
23638+
// the test.
23639+
bool OptForSize = DAG.getMachineFunction().getFunction().hasOptSize();
23640+
if (OptForSize && DAG.isKnownNeverZero(Amt)) {
2363923641
SDLoc DL(ArithOp);
2364023642

2364123643
// CopyToReg(CL, Amt)

llvm/test/CodeGen/X86/apx/shift-eflags.ll

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ define i32 @ashr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
265265
; CHECK-NEXT: movl %ecx, %eax
266266
; CHECK-NEXT: orb $1, %sil, %cl
267267
; CHECK-NEXT: sarl %cl, %edi
268+
; CHECK-NEXT: testl %edi, %edi
268269
; CHECK-NEXT: cmovel %edx, %eax
269270
; CHECK-NEXT: retq
270271
%a = or i32 %a1, 1
@@ -281,6 +282,7 @@ define i32 @lshr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
281282
; CHECK-NEXT: movl %ecx, %eax
282283
; CHECK-NEXT: orb $1, %sil, %cl
283284
; CHECK-NEXT: shrl %cl, %edi
285+
; CHECK-NEXT: testl %edi, %edi
284286
; CHECK-NEXT: cmovel %edx, %eax
285287
; CHECK-NEXT: retq
286288
%a = or i32 %a1, 1
@@ -297,6 +299,7 @@ define i32 @shl_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
297299
; CHECK-NEXT: movl %ecx, %eax
298300
; CHECK-NEXT: orb $1, %sil, %cl
299301
; CHECK-NEXT: shll %cl, %edi
302+
; CHECK-NEXT: testl %edi, %edi
300303
; CHECK-NEXT: cmovel %edx, %eax
301304
; CHECK-NEXT: retq
302305
%a = or i32 %a1, 1
@@ -312,6 +315,7 @@ define i32 @ashr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %
312315
; CHECK: # %bb.0:
313316
; CHECK-NEXT: orb $1, %sil, %cl
314317
; CHECK-NEXT: shrl %cl, %edi, %eax
318+
; CHECK-NEXT: testl %eax, %eax
315319
; CHECK-NEXT: cmovnel %edx, %eax
316320
; CHECK-NEXT: retq
317321
%a = or i32 %a1, 1
@@ -327,6 +331,7 @@ define i32 @lshr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %
327331
; CHECK: # %bb.0:
328332
; CHECK-NEXT: orb $1, %sil, %cl
329333
; CHECK-NEXT: shrl %cl, %edi, %eax
334+
; CHECK-NEXT: testl %eax, %eax
330335
; CHECK-NEXT: cmovnel %edx, %eax
331336
; CHECK-NEXT: retq
332337
%a = or i32 %a1, 1
@@ -342,6 +347,7 @@ define i32 @shl_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a
342347
; CHECK: # %bb.0:
343348
; CHECK-NEXT: orb $1, %sil, %cl
344349
; CHECK-NEXT: shrl %cl, %edi, %eax
350+
; CHECK-NEXT: testl %eax, %eax
345351
; CHECK-NEXT: cmovnel %edx, %eax
346352
; CHECK-NEXT: retq
347353
%a = or i32 %a1, 1
@@ -351,19 +357,83 @@ define i32 @shl_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a
351357
ret i32 %r
352358
}
353359

354-
define range(i8 0, 2) i8 @no_test_emitted_when_assume_shift_amt_gt_zero(i64 noundef %0, i32 noundef %1) {
355-
; CHECK-LABEL: no_test_emitted_when_assume_shift_amt_gt_zero:
360+
define i1 @shl_optsize_nonzero_removes_test(i32 %val, i32 %amt) optsize {
361+
; CHECK-LABEL: shl_optsize_nonzero_removes_test:
362+
; CHECK: # %bb.0:
363+
; CHECK-NEXT: orb $1, %sil, %cl
364+
; CHECK-NEXT: shll %cl, %edi
365+
; CHECK-NEXT: sete %al
366+
; CHECK-NEXT: retq
367+
%amt.nz = or i32 %amt, 1
368+
%shl = shl i32 %val, %amt.nz
369+
%cmp = icmp eq i32 %shl, 0
370+
ret i1 %cmp
371+
}
372+
373+
define i1 @shl_optsize_maybezero_keeps_test(i32 %val, i32 %amt) optsize {
374+
; CHECK-LABEL: shl_optsize_maybezero_keeps_test:
356375
; CHECK: # %bb.0:
357376
; CHECK-NEXT: movl %esi, %ecx
358377
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
359-
; CHECK-NEXT: shlq %cl, %rdi
378+
; CHECK-NEXT: shll %cl, %edi
379+
; CHECK-NEXT: testl %edi, %edi
380+
; CHECK-NEXT: sete %al
381+
; CHECK-NEXT: retq
382+
%shl = shl i32 %val, %amt
383+
%cmp = icmp eq i32 %shl, 0
384+
ret i1 %cmp
385+
}
386+
387+
define i1 @lshr_optsize_nonezero_removes_test(i32 %val, i32 %amt) optsize {
388+
; CHECK-LABEL: lshr_optsize_nonezero_removes_test:
389+
; CHECK: # %bb.0:
390+
; CHECK-NEXT: orb $1, %sil, %cl
391+
; CHECK-NEXT: shrl %cl, %edi
392+
; CHECK-NEXT: sete %al
393+
; CHECK-NEXT: retq
394+
%amt.nz = or i32 %amt, 1
395+
%shr = lshr i32 %val, %amt.nz
396+
%cmp = icmp eq i32 %shr, 0
397+
ret i1 %cmp
398+
}
399+
400+
define i1 @lshr_optsize_maybezero_keeps_test(i32 %val, i32 %amt) optsize {
401+
; CHECK-LABEL: lshr_optsize_maybezero_keeps_test:
402+
; CHECK: # %bb.0:
403+
; CHECK-NEXT: movl %esi, %ecx
404+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
405+
; CHECK-NEXT: shrl %cl, %edi
406+
; CHECK-NEXT: testl %edi, %edi
407+
; CHECK-NEXT: sete %al
408+
; CHECK-NEXT: retq
409+
%shr = lshr i32 %val, %amt
410+
%cmp = icmp eq i32 %shr, 0
411+
ret i1 %cmp
412+
}
413+
414+
define i1 @ashr_optsize_nonezero_removes_test(i32 %val, i32 %amt) optsize {
415+
; CHECK-LABEL: ashr_optsize_nonezero_removes_test:
416+
; CHECK: # %bb.0:
417+
; CHECK-NEXT: orb $1, %sil, %cl
418+
; CHECK-NEXT: sarl %cl, %edi
419+
; CHECK-NEXT: sete %al
420+
; CHECK-NEXT: retq
421+
%amt.nz = or i32 %amt, 1
422+
%sar = ashr i32 %val, %amt.nz
423+
%cmp = icmp eq i32 %sar, 0
424+
ret i1 %cmp
425+
}
426+
427+
define i1 @ashr_optsize_maybezero_keeps_test(i32 %val, i32 %amt) optsize {
428+
; CHECK-LABEL: ashr_optsize_maybezero_keeps_test:
429+
; CHECK: # %bb.0:
430+
; CHECK-NEXT: movl %esi, %ecx
431+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
432+
; CHECK-NEXT: sarl %cl, %edi
433+
; CHECK-NEXT: testl %edi, %edi
360434
; CHECK-NEXT: sete %al
361435
; CHECK-NEXT: retq
362-
%3 = icmp sgt i32 %1, 0
363-
tail call void @llvm.assume(i1 %3)
364-
%4 = zext nneg i32 %1 to i64
365-
%5 = shl i64 %0, %4
366-
%6 = icmp eq i64 %5, 0
367-
%7 = zext i1 %6 to i8
368-
ret i8 %7
436+
%sar = ashr i32 %val, %amt
437+
%cmp = icmp eq i32 %sar, 0
438+
ret i1 %cmp
369439
}

llvm/test/CodeGen/X86/shift-eflags.ll

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ define i32 @ashr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
282282
; CHECK-NEXT: orb $1, %cl
283283
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
284284
; CHECK-NEXT: sarl %cl, %edi
285+
; CHECK-NEXT: testl %edi, %edi
285286
; CHECK-NEXT: cmovel %edx, %eax
286287
; CHECK-NEXT: retq
287288
%a = or i32 %a1, 1
@@ -300,6 +301,7 @@ define i32 @lshr_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
300301
; CHECK-NEXT: orb $1, %cl
301302
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
302303
; CHECK-NEXT: shrl %cl, %edi
304+
; CHECK-NEXT: testl %edi, %edi
303305
; CHECK-NEXT: cmovel %edx, %eax
304306
; CHECK-NEXT: retq
305307
%a = or i32 %a1, 1
@@ -318,6 +320,7 @@ define i32 @shl_var_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
318320
; CHECK-NEXT: orb $1, %cl
319321
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
320322
; CHECK-NEXT: shll %cl, %edi
323+
; CHECK-NEXT: testl %edi, %edi
321324
; CHECK-NEXT: cmovel %edx, %eax
322325
; CHECK-NEXT: retq
323326
%a = or i32 %a1, 1
@@ -336,6 +339,7 @@ define i32 @ashr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %
336339
; CHECK-NEXT: orb $1, %cl
337340
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
338341
; CHECK-NEXT: shrl %cl, %eax
342+
; CHECK-NEXT: testl %eax, %eax
339343
; CHECK-NEXT: cmovnel %edx, %eax
340344
; CHECK-NEXT: retq
341345
%a = or i32 %a1, 1
@@ -354,6 +358,7 @@ define i32 @lshr_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %
354358
; CHECK-NEXT: orb $1, %cl
355359
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
356360
; CHECK-NEXT: shrl %cl, %eax
361+
; CHECK-NEXT: testl %eax, %eax
357362
; CHECK-NEXT: cmovnel %edx, %eax
358363
; CHECK-NEXT: retq
359364
%a = or i32 %a1, 1
@@ -372,6 +377,7 @@ define i32 @shl_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a
372377
; CHECK-NEXT: orb $1, %cl
373378
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
374379
; CHECK-NEXT: shrl %cl, %eax
380+
; CHECK-NEXT: testl %eax, %eax
375381
; CHECK-NEXT: cmovnel %edx, %eax
376382
; CHECK-NEXT: retq
377383
%a = or i32 %a1, 1
@@ -381,19 +387,89 @@ define i32 @shl_var_self_select_amt_never_zero(i32 %a0, i32 %a1, i32 %a2, i32 %a
381387
ret i32 %r
382388
}
383389

384-
define range(i8 0, 2) i8 @no_test_emitted_when_assume_shift_amt_gt_zero(i64 noundef %0, i32 noundef %1) {
385-
; CHECK-LABEL: no_test_emitted_when_assume_shift_amt_gt_zero:
390+
define i1 @shl_optsize_nonzero_removes_test(i32 %val, i32 %amt) optsize {
391+
; CHECK-LABEL: shl_optsize_nonzero_removes_test:
386392
; CHECK: # %bb.0:
387393
; CHECK-NEXT: movl %esi, %ecx
394+
; CHECK-NEXT: orb $1, %cl
388395
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
389-
; CHECK-NEXT: shlq %cl, %rdi
396+
; CHECK-NEXT: shll %cl, %edi
397+
; CHECK-NEXT: sete %al
398+
; CHECK-NEXT: retq
399+
%amt.nz = or i32 %amt, 1
400+
%shl = shl i32 %val, %amt.nz
401+
%cmp = icmp eq i32 %shl, 0
402+
ret i1 %cmp
403+
}
404+
405+
define i1 @shl_optsize_maybezero_keeps_test(i32 %val, i32 %amt) optsize {
406+
; CHECK-LABEL: shl_optsize_maybezero_keeps_test:
407+
; CHECK: # %bb.0:
408+
; CHECK-NEXT: movl %esi, %ecx
409+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
410+
; CHECK-NEXT: shll %cl, %edi
411+
; CHECK-NEXT: testl %edi, %edi
412+
; CHECK-NEXT: sete %al
413+
; CHECK-NEXT: retq
414+
%shl = shl i32 %val, %amt
415+
%cmp = icmp eq i32 %shl, 0
416+
ret i1 %cmp
417+
}
418+
419+
define i1 @lshr_optsize_nonezero_removes_test(i32 %val, i32 %amt) optsize {
420+
; CHECK-LABEL: lshr_optsize_nonezero_removes_test:
421+
; CHECK: # %bb.0:
422+
; CHECK-NEXT: movl %esi, %ecx
423+
; CHECK-NEXT: orb $1, %cl
424+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
425+
; CHECK-NEXT: shrl %cl, %edi
426+
; CHECK-NEXT: sete %al
427+
; CHECK-NEXT: retq
428+
%amt.nz = or i32 %amt, 1
429+
%shr = lshr i32 %val, %amt.nz
430+
%cmp = icmp eq i32 %shr, 0
431+
ret i1 %cmp
432+
}
433+
434+
define i1 @lshr_optsize_maybezero_keeps_test(i32 %val, i32 %amt) optsize {
435+
; CHECK-LABEL: lshr_optsize_maybezero_keeps_test:
436+
; CHECK: # %bb.0:
437+
; CHECK-NEXT: movl %esi, %ecx
438+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
439+
; CHECK-NEXT: shrl %cl, %edi
440+
; CHECK-NEXT: testl %edi, %edi
441+
; CHECK-NEXT: sete %al
442+
; CHECK-NEXT: retq
443+
%shr = lshr i32 %val, %amt
444+
%cmp = icmp eq i32 %shr, 0
445+
ret i1 %cmp
446+
}
447+
448+
define i1 @ashr_optsize_nonezero_removes_test(i32 %val, i32 %amt) optsize {
449+
; CHECK-LABEL: ashr_optsize_nonezero_removes_test:
450+
; CHECK: # %bb.0:
451+
; CHECK-NEXT: movl %esi, %ecx
452+
; CHECK-NEXT: orb $1, %cl
453+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
454+
; CHECK-NEXT: sarl %cl, %edi
455+
; CHECK-NEXT: sete %al
456+
; CHECK-NEXT: retq
457+
%amt.nz = or i32 %amt, 1
458+
%sar = ashr i32 %val, %amt.nz
459+
%cmp = icmp eq i32 %sar, 0
460+
ret i1 %cmp
461+
}
462+
463+
define i1 @ashr_optsize_maybezero_keeps_test(i32 %val, i32 %amt) optsize {
464+
; CHECK-LABEL: ashr_optsize_maybezero_keeps_test:
465+
; CHECK: # %bb.0:
466+
; CHECK-NEXT: movl %esi, %ecx
467+
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
468+
; CHECK-NEXT: sarl %cl, %edi
469+
; CHECK-NEXT: testl %edi, %edi
390470
; CHECK-NEXT: sete %al
391471
; CHECK-NEXT: retq
392-
%3 = icmp sgt i32 %1, 0
393-
tail call void @llvm.assume(i1 %3)
394-
%4 = zext nneg i32 %1 to i64
395-
%5 = shl i64 %0, %4
396-
%6 = icmp eq i64 %5, 0
397-
%7 = zext i1 %6 to i8
398-
ret i8 %7
472+
%sar = ashr i32 %val, %amt
473+
%cmp = icmp eq i32 %sar, 0
474+
ret i1 %cmp
399475
}

0 commit comments

Comments
 (0)