From a49cebb751b23b69279ac19344c90c5a807d6494 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Fri, 2 May 2025 00:39:16 +0800 Subject: [PATCH] [InstSimplify] Fold {u,s}{min,max} x, poison -> poison Following from the discussion in https://github.com/llvm/llvm-project/pull/138095#discussion_r2070484664, these intrinsics are poison if any of their operands are poison, and are marked as such in propagatesPoison in ValueTracking.cpp. This will help fold away leftover vectors produced by VectorCombine when scalarizing intrinsics. --- llvm/lib/Analysis/InstructionSimplify.cpp | 4 ++++ llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 8ffb471070d91..275ca8fa4dbc2 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -6549,6 +6549,10 @@ Value *llvm::simplifyBinaryIntrinsic(Intrinsic::ID IID, Type *ReturnType, if (match(Op0, m_ImmConstant())) std::swap(Op0, Op1); + // Propagate poison. + if (isa(Op1)) + return Op1; + // Assume undef is the limit value. if (Q.isUndefValue(Op1)) return ConstantInt::get( diff --git a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll index ddd4140b3aedd..98bfe5329c290 100644 --- a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll +++ b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll @@ -75,7 +75,7 @@ define i81 @smax_undef(i81 %x) { define i81 @smax_poison(i81 %x) { ; CHECK-LABEL: @smax_poison( -; CHECK-NEXT: ret i81 1208925819614629174706175 +; CHECK-NEXT: ret i81 poison ; %r = call i81 @llvm.smax.i81(i81 poison, i81 %x) ret i81 %r @@ -91,7 +91,7 @@ define i3 @smin_undef(i3 %x) { define i3 @smin_poison(i3 %x) { ; CHECK-LABEL: @smin_poison( -; CHECK-NEXT: ret i3 -4 +; CHECK-NEXT: ret i3 poison ; %r = call i3 @llvm.smin.i3(i3 %x, i3 poison) ret i3 %r @@ -107,7 +107,7 @@ define <2 x i8> @umax_undef(<2 x i8> %x) { define <2 x i8> @umax_poison(<2 x i8> %x) { ; CHECK-LABEL: @umax_poison( -; CHECK-NEXT: ret <2 x i8> splat (i8 -1) +; CHECK-NEXT: ret <2 x i8> poison ; %r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> poison, <2 x i8> %x) ret <2 x i8> %r @@ -123,7 +123,7 @@ define <2 x i8> @umin_undef(<2 x i8> %x) { define <2 x i8> @umin_poison(<2 x i8> %x) { ; CHECK-LABEL: @umin_poison( -; CHECK-NEXT: ret <2 x i8> zeroinitializer +; CHECK-NEXT: ret <2 x i8> poison ; %r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> poison) ret <2 x i8> %r