1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[instcombine] umin(x, 1) == zext(x != 0)

We already implemented this for the select form, but the intrinsic form was missing.  Note that this doesn't change poison behavior as 1 is non-poison, and the optimized form is still poison exactly when x is.
This commit is contained in:
Philip Reames 2021-06-30 10:18:38 -07:00
parent fcb829d489
commit 884ef85b3f
2 changed files with 51 additions and 1 deletions

View File

@ -956,8 +956,17 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
break; break;
} }
case Intrinsic::umax:
case Intrinsic::umin: { case Intrinsic::umin: {
Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
// umin(x, 1) == zext(x != 0)
if (match(I1, m_One())) {
Value *Zero = Constant::getNullValue(I0->getType());
Value *Cmp = Builder.CreateICmpNE(I0, Zero);
return CastInst::Create(Instruction::ZExt, Cmp, II->getType());
}
LLVM_FALLTHROUGH;
}
case Intrinsic::umax: {
Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1); Value *I0 = II->getArgOperand(0), *I1 = II->getArgOperand(1);
Value *X, *Y; Value *X, *Y;
if (match(I0, m_ZExt(m_Value(X))) && match(I1, m_ZExt(m_Value(Y))) && if (match(I0, m_ZExt(m_Value(X))) && match(I1, m_ZExt(m_Value(Y))) &&

View File

@ -817,3 +817,44 @@ define i8 @clamp_two_vals_smin_smax_edge(i8 %x) {
%r = call i8 @llvm.smax.i8(i8 %m, i8 127) %r = call i8 @llvm.smax.i8(i8 %m, i8 127)
ret i8 %r ret i8 %r
} }
define i8 @umin_non_zero_idiom1(i8 %a) {
; CHECK-LABEL: @umin_non_zero_idiom1(
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
; CHECK-NEXT: [[RES:%.*]] = zext i1 [[TMP1]] to i8
; CHECK-NEXT: ret i8 [[RES]]
;
%res = call i8 @llvm.umin.i8(i8 %a, i8 1)
ret i8 %res
}
define i8 @umin_non_zero_idiom2(i8 %a) {
; CHECK-LABEL: @umin_non_zero_idiom2(
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
; CHECK-NEXT: [[RES:%.*]] = zext i1 [[TMP1]] to i8
; CHECK-NEXT: ret i8 [[RES]]
;
%res = call i8 @llvm.umin.i8(i8 1, i8 %a)
ret i8 %res
}
define <3 x i8> @umin_non_zero_idiom3(<3 x i8> %a) {
; CHECK-LABEL: @umin_non_zero_idiom3(
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[A:%.*]], zeroinitializer
; CHECK-NEXT: [[RES:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i8>
; CHECK-NEXT: ret <3 x i8> [[RES]]
;
%res = call <3 x i8> @llvm.umin.v3i8(<3 x i8> %a, <3 x i8> <i8 1, i8 1, i8 1>)
ret <3 x i8> %res
}
define <3 x i8> @umin_non_zero_idiom4(<3 x i8> %a) {
; CHECK-LABEL: @umin_non_zero_idiom4(
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <3 x i8> [[A:%.*]], zeroinitializer
; CHECK-NEXT: [[RES:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i8>
; CHECK-NEXT: ret <3 x i8> [[RES]]
;
%res = call <3 x i8> @llvm.umin.v3i8(<3 x i8> %a, <3 x i8> <i8 1, i8 undef, i8 undef>)
ret <3 x i8> %res
}