[llvm] [ConstFold] Eliminate some undef-folding, with tests (PR #207184)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 2 06:14:48 PDT 2026
https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/207184
The patch is merely a cleanup: undef-folding is no longer useful these days.
>From c8c0a46fcdadc2a3914896fc4e85172a52a74ff6 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Fri, 12 Jun 2026 11:36:57 +0100
Subject: [PATCH] [ConstFold] Eliminate some undef-folding, with tests
The patch is merely a cleanup: undef-folding is no longer useful these
days.
---
llvm/lib/Analysis/ConstantFolding.cpp | 7 -
.../InstSimplify/ConstProp/cttz-elts.ll | 16 --
.../ConstProp/saturating-add-sub.ll | 194 ------------------
3 files changed, 217 deletions(-)
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 7fd1e60033437..1d17f6a6cc2c7 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2350,7 +2350,6 @@ Constant *constantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) {
if (!VT)
return nullptr;
- // TODO: Handle undef.
auto *EltC = dyn_cast_or_null<ConstantInt>(Op->getAggregateElement(0U));
if (!EltC)
return nullptr;
@@ -3781,8 +3780,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
case Intrinsic::smin:
case Intrinsic::umax:
case Intrinsic::umin:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
if (!C0 || !C1)
return MinMaxIntrinsic::getSaturationPoint(IntrinsicID, Ty);
return ConstantInt::get(
@@ -3859,8 +3856,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
}
case Intrinsic::uadd_sat:
case Intrinsic::sadd_sat:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
if (!C0 || !C1)
return Constant::getAllOnesValue(Ty);
if (IntrinsicID == Intrinsic::uadd_sat)
@@ -3869,8 +3864,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
return ConstantInt::get(Ty, C0->sadd_sat(*C1));
case Intrinsic::usub_sat:
case Intrinsic::ssub_sat:
- if (!C0 && !C1)
- return UndefValue::get(Ty);
if (!C0 || !C1)
return Constant::getNullValue(Ty);
if (IntrinsicID == Intrinsic::usub_sat)
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/cttz-elts.ll b/llvm/test/Transforms/InstSimplify/ConstProp/cttz-elts.ll
index db91fd68fcbe6..2faac784d0a66 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/cttz-elts.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/cttz-elts.ll
@@ -25,22 +25,6 @@ define i32 @cttz_elts_v4i32() {
ret i32 %res
}
-define i32 @cttz_elts_v4i32_unused_lane_undef() {
-; CHECK-LABEL: @cttz_elts_v4i32_unused_lane_undef(
-; CHECK-NEXT: ret i32 1
-;
- %res = call i32 @llvm.experimental.cttz.elts.i32.v4i32(<4 x i32> <i32 0, i32 1, i32 undef, i32 3>, i1 false)
- ret i32 %res
-}
-
-define i32 @cttz_elts_v4i32_used_lane_undef() {
-; CHECK-LABEL: @cttz_elts_v4i32_used_lane_undef(
-; CHECK-NEXT: ret i32 3
-;
- %res = call i32 @llvm.experimental.cttz.elts.i32.v4i32(<4 x i32> <i32 0, i32 0, i32 undef, i32 3>, i1 false)
- ret i32 %res
-}
-
define i32 @cttz_elts_v4i32_unused_lane_poison() {
; CHECK-LABEL: @cttz_elts_v4i32_unused_lane_poison(
; CHECK-NEXT: ret i32 1
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll b/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll
index fde98c43e7687..59e6e433e7663 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/saturating-add-sub.ll
@@ -171,200 +171,6 @@ define <2 x i8> @test_ssub_vector_sat_neg(<2 x i8> %a) {
ret <2 x i8> %x
}
-; Tests for undef handling
-
-define i8 @test_uadd_scalar_both_undef() {
-; CHECK-LABEL: @test_uadd_scalar_both_undef(
-; CHECK-NEXT: ret i8 undef
-;
- %x = call i8 @llvm.uadd.sat.i8(i8 undef, i8 undef)
- ret i8 %x
-}
-
-define i8 @test_sadd_scalar_both_undef() {
-; CHECK-LABEL: @test_sadd_scalar_both_undef(
-; CHECK-NEXT: ret i8 undef
-;
- %x = call i8 @llvm.sadd.sat.i8(i8 undef, i8 undef)
- ret i8 %x
-}
-
-define i8 @test_usub_scalar_both_undef() {
-; CHECK-LABEL: @test_usub_scalar_both_undef(
-; CHECK-NEXT: ret i8 undef
-;
- %x = call i8 @llvm.usub.sat.i8(i8 undef, i8 undef)
- ret i8 %x
-}
-
-define i8 @test_ssub_scalar_both_undef() {
-; CHECK-LABEL: @test_ssub_scalar_both_undef(
-; CHECK-NEXT: ret i8 undef
-;
- %x = call i8 @llvm.ssub.sat.i8(i8 undef, i8 undef)
- ret i8 %x
-}
-
-define i8 @test_uadd_scalar_op2_undef() {
-; CHECK-LABEL: @test_uadd_scalar_op2_undef(
-; CHECK-NEXT: ret i8 -1
-;
- %x = call i8 @llvm.uadd.sat.i8(i8 10, i8 undef)
- ret i8 %x
-}
-
-define i8 @test_sadd_scalar_op1_undef() {
-; CHECK-LABEL: @test_sadd_scalar_op1_undef(
-; CHECK-NEXT: ret i8 -1
-;
- %x = call i8 @llvm.sadd.sat.i8(i8 undef, i8 10)
- ret i8 %x
-}
-
-define i8 @test_usub_scalar_op2_undef() {
-; CHECK-LABEL: @test_usub_scalar_op2_undef(
-; CHECK-NEXT: ret i8 0
-;
- %x = call i8 @llvm.usub.sat.i8(i8 10, i8 undef)
- ret i8 %x
-}
-
-define i8 @test_usub_scalar_op1_undef() {
-; CHECK-LABEL: @test_usub_scalar_op1_undef(
-; CHECK-NEXT: ret i8 0
-;
- %x = call i8 @llvm.usub.sat.i8(i8 undef, i8 10)
- ret i8 %x
-}
-
-define <2 x i8> @test_uadd_vector_both_undef_splat() {
-; CHECK-LABEL: @test_uadd_vector_both_undef_splat(
-; CHECK-NEXT: ret <2 x i8> undef
-;
- %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_sadd_vector_both_undef_splat() {
-; CHECK-LABEL: @test_sadd_vector_both_undef_splat(
-; CHECK-NEXT: ret <2 x i8> undef
-;
- %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_usub_vector_both_undef_splat() {
-; CHECK-LABEL: @test_usub_vector_both_undef_splat(
-; CHECK-NEXT: ret <2 x i8> undef
-;
- %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_ssub_vector_both_undef_splat() {
-; CHECK-LABEL: @test_ssub_vector_both_undef_splat(
-; CHECK-NEXT: ret <2 x i8> undef
-;
- %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> undef, <2 x i8> undef)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_uadd_vector_op2_undef_splat() {
-; CHECK-LABEL: @test_uadd_vector_op2_undef_splat(
-; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
-;
- %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> undef)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_sadd_vector_op1_undef_splat() {
-; CHECK-LABEL: @test_sadd_vector_op1_undef_splat(
-; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
-;
- %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> undef, <2 x i8> <i8 10, i8 20>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_usub_vector_op2_undef_splat() {
-; CHECK-LABEL: @test_usub_vector_op2_undef_splat(
-; CHECK-NEXT: ret <2 x i8> zeroinitializer
-;
- %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 20>, <2 x i8> undef)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_ssub_vector_op1_undef_splat() {
-; CHECK-LABEL: @test_ssub_vector_op1_undef_splat(
-; CHECK-NEXT: ret <2 x i8> zeroinitializer
-;
- %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> undef, <2 x i8> <i8 10, i8 20>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_uadd_vector_op2_undef_mix1() {
-; CHECK-LABEL: @test_uadd_vector_op2_undef_mix1(
-; CHECK-NEXT: ret <2 x i8> <i8 30, i8 undef>
-;
- %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 20, i8 undef>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_uadd_vector_op2_undef_mix2() {
-; CHECK-LABEL: @test_uadd_vector_op2_undef_mix2(
-; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
-;
- %x = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 undef, i8 20>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_sadd_vector_op1_undef_mix1() {
-; CHECK-LABEL: @test_sadd_vector_op1_undef_mix1(
-; CHECK-NEXT: ret <2 x i8> <i8 undef, i8 30>
-;
- %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 undef, i8 20>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_sadd_vector_op1_undef_mix2() {
-; CHECK-LABEL: @test_sadd_vector_op1_undef_mix2(
-; CHECK-NEXT: ret <2 x i8> splat (i8 -1)
-;
- %x = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 20, i8 undef>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_usub_vector_op2_undef_mix1() {
-; CHECK-LABEL: @test_usub_vector_op2_undef_mix1(
-; CHECK-NEXT: ret <2 x i8> <i8 0, i8 undef>
-;
- %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 20, i8 undef>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_usub_vector_op2_undef_mix2() {
-; CHECK-LABEL: @test_usub_vector_op2_undef_mix2(
-; CHECK-NEXT: ret <2 x i8> zeroinitializer
-;
- %x = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> <i8 10, i8 undef>, <2 x i8> <i8 undef, i8 20>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_ssub_vector_op1_undef_mix1() {
-; CHECK-LABEL: @test_ssub_vector_op1_undef_mix1(
-; CHECK-NEXT: ret <2 x i8> <i8 undef, i8 -10>
-;
- %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 undef, i8 20>)
- ret <2 x i8> %x
-}
-
-define <2 x i8> @test_ssub_vector_op1_undef_mix2() {
-; CHECK-LABEL: @test_ssub_vector_op1_undef_mix2(
-; CHECK-NEXT: ret <2 x i8> zeroinitializer
-;
- %x = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> <i8 undef, i8 10>, <2 x i8> <i8 20, i8 undef>)
- ret <2 x i8> %x
-}
-
; Tests for poison handling
define i8 @test_uadd_scalar_both_poison() {
More information about the llvm-commits
mailing list