diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll --- a/llvm/test/CodeGen/X86/known-never-zero.ll +++ b/llvm/test/CodeGen/X86/known-never-zero.ll @@ -8,6 +8,8 @@ declare i32 @llvm.uadd.sat.i32(i32, i32) declare i32 @llvm.umax.i32(i32, i32) declare i32 @llvm.umin.i32(i32, i32) +declare i32 @llvm.smin.i32(i32, i32) +declare i32 @llvm.smax.i32(i32, i32) declare i32 @llvm.bswap.i32(i32) declare i32 @llvm.bitreverse.i32(i32) declare i32 @llvm.ctpop.i32(i32) @@ -246,6 +248,82 @@ ret i32 %r } +define i32 @smin_known_nonzero(i32 %xx, i32 %yy) { +; CHECK-LABEL: smin_known_nonzero: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %ecx +; CHECK-NEXT: movl $4, %eax +; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx +; CHECK-NEXT: shll %cl, %eax +; CHECK-NEXT: addl $4, %esi +; CHECK-NEXT: cmpl %esi, %eax +; CHECK-NEXT: cmovll %eax, %esi +; CHECK-NEXT: bsfl %esi, %ecx +; CHECK-NEXT: movl $32, %eax +; CHECK-NEXT: cmovnel %ecx, %eax +; CHECK-NEXT: retq + %x = shl nuw i32 4, %xx + %y = add nuw nsw i32 %yy, 4 + %z = call i32 @llvm.smin.i32(i32 %x, i32 %y) + %r = call i32 @llvm.cttz.i32(i32 %z, i1 false) + ret i32 %r +} + +define i32 @smin_maybe_zero(i32 %x, i32 %y) { +; CHECK-LABEL: smin_maybe_zero: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpl $54, %edi +; CHECK-NEXT: movl $54, %eax +; CHECK-NEXT: cmovll %edi, %eax +; CHECK-NEXT: testl %eax, %eax +; CHECK-NEXT: je .LBB15_1 +; CHECK-NEXT: # %bb.2: # %cond.false +; CHECK-NEXT: rep bsfl %eax, %eax +; CHECK-NEXT: retq +; CHECK-NEXT: .LBB15_1: +; CHECK-NEXT: movl $32, %eax +; CHECK-NEXT: retq + %z = call i32 @llvm.smin.i32(i32 %x, i32 54) + %r = call i32 @llvm.cttz.i32(i32 %z, i1 false) + ret i32 %r +} + +define i32 @smax_known_nonzero(i32 %xx, i32 %yy) { +; CHECK-LABEL: smax_known_nonzero: +; CHECK: # %bb.0: +; CHECK-NEXT: movl %edi, %ecx +; CHECK-NEXT: movl $4, %eax +; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx +; CHECK-NEXT: shll %cl, %eax +; CHECK-NEXT: addl $4, %esi +; CHECK-NEXT: cmpl %esi, %eax +; CHECK-NEXT: cmovgl %eax, %esi +; CHECK-NEXT: bsfl %esi, %ecx +; CHECK-NEXT: movl $32, %eax +; CHECK-NEXT: cmovnel %ecx, %eax +; CHECK-NEXT: retq + %x = shl nuw i32 4, %xx + %y = add nuw nsw i32 %yy, 4 + %z = call i32 @llvm.smax.i32(i32 %x, i32 %y) + %r = call i32 @llvm.cttz.i32(i32 %z, i1 false) + ret i32 %r +} + +define i32 @smax_maybe_zero(i32 %x, i32 %y) { +; CHECK-LABEL: smax_maybe_zero: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpl $55, %edi +; CHECK-NEXT: movl $54, %eax +; CHECK-NEXT: cmovgel %edi, %eax +; CHECK-NEXT: bsfl %eax, %ecx +; CHECK-NEXT: movl $32, %eax +; CHECK-NEXT: cmovnel %ecx, %eax +; CHECK-NEXT: retq + %z = call i32 @llvm.smax.i32(i32 %x, i32 54) + %r = call i32 @llvm.cttz.i32(i32 %z, i1 false) + ret i32 %r +} + define i32 @rotr_known_nonzero(i32 %xx, i32 %y) { ; CHECK-LABEL: rotr_known_nonzero: ; CHECK: # %bb.0: @@ -254,11 +332,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: rorl %cl, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB14_1 +; CHECK-NEXT: je .LBB18_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB14_1: +; CHECK-NEXT: .LBB18_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %x = or i32 %xx, 256 @@ -277,11 +355,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: rorl %cl, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB15_1 +; CHECK-NEXT: je .LBB19_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB15_1: +; CHECK-NEXT: .LBB19_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %shr = lshr i32 %x, %y @@ -314,11 +392,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: rorl %cl, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB17_1 +; CHECK-NEXT: je .LBB21_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB17_1: +; CHECK-NEXT: .LBB21_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y) @@ -334,11 +412,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: roll %cl, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB18_1 +; CHECK-NEXT: je .LBB22_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB18_1: +; CHECK-NEXT: .LBB22_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %x = or i32 %xx, 256 @@ -357,11 +435,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: roll %cl, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB19_1 +; CHECK-NEXT: je .LBB23_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB19_1: +; CHECK-NEXT: .LBB23_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %shl = shl i32 %x, %y @@ -394,11 +472,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: roll %cl, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB21_1 +; CHECK-NEXT: je .LBB25_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB21_1: +; CHECK-NEXT: .LBB25_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %y) @@ -442,11 +520,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: sarl %cl, %esi ; CHECK-NEXT: testl %esi, %esi -; CHECK-NEXT: je .LBB24_1 +; CHECK-NEXT: je .LBB28_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %esi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB24_1: +; CHECK-NEXT: .LBB28_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = ashr exact i32 %y, %x @@ -490,11 +568,11 @@ ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx ; CHECK-NEXT: shrl %cl, %esi ; CHECK-NEXT: testl %esi, %esi -; CHECK-NEXT: je .LBB27_1 +; CHECK-NEXT: je .LBB31_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %esi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB27_1: +; CHECK-NEXT: .LBB31_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = lshr exact i32 %y, %x @@ -524,11 +602,11 @@ ; CHECK-NEXT: xorl %edx, %edx ; CHECK-NEXT: divl %esi ; CHECK-NEXT: testl %eax, %eax -; CHECK-NEXT: je .LBB29_1 +; CHECK-NEXT: je .LBB33_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB29_1: +; CHECK-NEXT: .LBB33_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = udiv exact i32 %x, %y @@ -558,11 +636,11 @@ ; CHECK-NEXT: cltd ; CHECK-NEXT: idivl %esi ; CHECK-NEXT: testl %eax, %eax -; CHECK-NEXT: je .LBB31_1 +; CHECK-NEXT: je .LBB35_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB31_1: +; CHECK-NEXT: .LBB35_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = sdiv exact i32 %x, %y @@ -588,11 +666,11 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: orl $1, %edi ; CHECK-NEXT: addl %esi, %edi -; CHECK-NEXT: je .LBB33_1 +; CHECK-NEXT: je .LBB37_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB33_1: +; CHECK-NEXT: .LBB37_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %x = or i32 %xx, 1 @@ -639,11 +717,11 @@ ; CHECK-NEXT: movl %edi, %eax ; CHECK-NEXT: orl $64, %eax ; CHECK-NEXT: subl %edi, %eax -; CHECK-NEXT: je .LBB36_1 +; CHECK-NEXT: je .LBB40_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB36_1: +; CHECK-NEXT: .LBB40_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %y = or i32 %x, 64 @@ -656,11 +734,11 @@ ; CHECK-LABEL: sub_maybe_zero2: ; CHECK: # %bb.0: ; CHECK-NEXT: negl %edi -; CHECK-NEXT: je .LBB37_1 +; CHECK-NEXT: je .LBB41_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB37_1: +; CHECK-NEXT: .LBB41_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = sub i32 0, %x @@ -674,11 +752,11 @@ ; CHECK-NEXT: orl $256, %esi # imm = 0x100 ; CHECK-NEXT: imull %edi, %esi ; CHECK-NEXT: testl %esi, %esi -; CHECK-NEXT: je .LBB38_1 +; CHECK-NEXT: je .LBB42_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %esi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB38_1: +; CHECK-NEXT: .LBB42_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %y = or i32 %yy, 256 @@ -693,11 +771,11 @@ ; CHECK-NEXT: orl $256, %esi # imm = 0x100 ; CHECK-NEXT: imull %edi, %esi ; CHECK-NEXT: testl %esi, %esi -; CHECK-NEXT: je .LBB39_1 +; CHECK-NEXT: je .LBB43_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %esi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB39_1: +; CHECK-NEXT: .LBB43_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %y = or i32 %yy, 256 @@ -711,11 +789,11 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: imull %esi, %edi ; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: je .LBB40_1 +; CHECK-NEXT: je .LBB44_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %edi, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB40_1: +; CHECK-NEXT: .LBB44_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = mul nuw nsw i32 %y, %x @@ -748,11 +826,11 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: movd %xmm0, %eax ; CHECK-NEXT: testl %eax, %eax -; CHECK-NEXT: je .LBB42_1 +; CHECK-NEXT: je .LBB46_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB42_1: +; CHECK-NEXT: .LBB46_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = bitcast <2 x i16> %x to i32 @@ -765,11 +843,11 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: movd %xmm0, %eax ; CHECK-NEXT: testl %eax, %eax -; CHECK-NEXT: je .LBB43_1 +; CHECK-NEXT: je .LBB47_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB43_1: +; CHECK-NEXT: .LBB47_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = bitcast float %x to i32 @@ -797,12 +875,12 @@ ; CHECK-LABEL: zext_maybe_zero: ; CHECK: # %bb.0: ; CHECK-NEXT: testw %di, %di -; CHECK-NEXT: je .LBB45_1 +; CHECK-NEXT: je .LBB49_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: movzwl %di, %eax ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB45_1: +; CHECK-NEXT: .LBB49_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = zext i16 %x to i32 @@ -830,12 +908,12 @@ ; CHECK-LABEL: sext_maybe_zero: ; CHECK: # %bb.0: ; CHECK-NEXT: testw %di, %di -; CHECK-NEXT: je .LBB47_1 +; CHECK-NEXT: je .LBB51_1 ; CHECK-NEXT: # %bb.2: # %cond.false ; CHECK-NEXT: movswl %di, %eax ; CHECK-NEXT: rep bsfl %eax, %eax ; CHECK-NEXT: retq -; CHECK-NEXT: .LBB47_1: +; CHECK-NEXT: .LBB51_1: ; CHECK-NEXT: movl $32, %eax ; CHECK-NEXT: retq %z = sext i16 %x to i32