Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1085,7 +1085,7 @@ return BinaryOperator::CreateNot(InvMaxMin); } // max (not X), C --> not(min X, ~C) - if (match(I1, m_Constant(C)) && I0->hasOneUse()) { + if (match(I1, m_ImmConstant(C)) && I0->hasOneUse()) { Constant *NotC = ConstantExpr::getNot(C); Value *InvMaxMin = Builder.CreateBinaryIntrinsic(InvID, X, NotC); return BinaryOperator::CreateNot(InvMaxMin); Index: llvm/test/Transforms/InstCombine/minmax-intrinsics.ll =================================================================== --- llvm/test/Transforms/InstCombine/minmax-intrinsics.ll +++ llvm/test/Transforms/InstCombine/minmax-intrinsics.ll @@ -506,6 +506,17 @@ ret i8 %m } +define i8 @umin_of_not_and_nontrivial_const(i8 %x) { +; CHECK-LABEL: @umin_of_not_and_nontrivial_const( +; CHECK-NEXT: [[NOTX:%.*]] = xor i8 %x, -1 +; CHECK-NEXT: [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[NOTX]], i8 ptrtoint ({{.*}})) +; CHECK-NEXT: ret i8 [[M]] +; + %notx = xor i8 %x, -1 + %m = call i8 @llvm.umin.i8(i8 ptrtoint (i8(i8)* @umin_of_not_and_nontrivial_const to i8), i8 %notx) + ret i8 %m +} + ; Negative test - too many uses define i8 @umin_of_not_and_const_uses(i8 %x) {