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:
parent
fcb829d489
commit
884ef85b3f
@ -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))) &&
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user