diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1615,6 +1615,20 @@ } } + if ((IID == Intrinsic::umin || IID == Intrinsic::smax) && + (II->getType()->isIntOrIntVectorTy(1))) { + // umin(i1 X, i1 Y) -> and i1 X, Y + // smax(i1 X, i1 Y) -> and i1 X, Y + return BinaryOperator::CreateAnd(I0, I1); + } + + if ((IID == Intrinsic::umax || IID == Intrinsic::smin) && + (II->getType()->isIntOrIntVectorTy(1))) { + // umax(i1 X, i1 Y) -> or i1 X, Y + // smin(i1 X, i1 Y) -> or i1 X, Y + return BinaryOperator::CreateOr(I0, I1); + } + if (IID == Intrinsic::smax || IID == Intrinsic::smin) { // smax (neg nsw X), (neg nsw Y) --> neg nsw (smin X, Y) // smin (neg nsw X), (neg nsw Y) --> neg nsw (smax X, Y) diff --git a/llvm/test/Transforms/InstCombine/fold-minmax-i1.ll b/llvm/test/Transforms/InstCombine/fold-minmax-i1.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/fold-minmax-i1.ll @@ -0,0 +1,34 @@ +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i1 @umin(i1 %0, i1 %1) { +; CHECK-LABEL: @umin +; CHECK-NEXT: and i1 + %3 = call i1 @llvm.umin.i1(i1 %0, i1 %1) + ret i1 %3 +} + +define i1 @smin(i1 %0, i1 %1) { +; CHECK-LABEL: @smin +; CHECK-NEXT: or i1 + %3 = call i1 @llvm.smin.i1(i1 %0, i1 %1) + ret i1 %3 +} + +define i1 @umax(i1 %0, i1 %1) { +; CHECK-LABEL: @umax +; CHECK-NEXT: or i1 + %3 = call i1 @llvm.umax.i1(i1 %0, i1 %1) + ret i1 %3 +} + +define i1 @smax(i1 %0, i1 %1) { +; CHECK-LABEL: @smax +; CHECK-NEXT: and i1 + %3 = call i1 @llvm.smax.i1(i1 %0, i1 %1) + ret i1 %3 +} + +declare i1 @llvm.umin.i1(i1, i1) +declare i1 @llvm.smin.i1(i1, i1) +declare i1 @llvm.umax.i1(i1, i1) +declare i1 @llvm.smax.i1(i1, i1)