[llvm] [InstCombine] Fold `zext(X) | sext(X)` to `sext(X)` (PR #213313)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 31 10:28:56 PDT 2026


https://github.com/VachanVY created https://github.com/llvm/llvm-project/pull/213313

fix #213247

>From 3b1996282d56e92b037fab5062450b55be478a7d Mon Sep 17 00:00:00 2001
From: Vachan V Y <vachanvy05 at gmail.com>
Date: Fri, 31 Jul 2026 22:56:37 +0530
Subject: [PATCH] [InstCombine] Precommit Tests. NFC

---
 .../InstCombine/fold-or-zext-sext.ll          | 124 ++++++++++++++++++
 1 file changed, 124 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/fold-or-zext-sext.ll

diff --git a/llvm/test/Transforms/InstCombine/fold-or-zext-sext.ll b/llvm/test/Transforms/InstCombine/fold-or-zext-sext.ll
new file mode 100644
index 0000000000000..719ae170a4112
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fold-or-zext-sext.ll
@@ -0,0 +1,124 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+declare void @use32(i32)
+
+define i32 @fold_zext_sext(i8 %x) {
+; CHECK-LABEL: @fold_zext_sext(
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[ZEXT]], [[SEXT]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %zext = zext i8 %x to i32
+  %sext = sext i8 %x to i32
+  %or = or i32 %zext, %sext
+  ret i32 %or
+}
+
+define i32 @fold_zext_sext_commuted(i8 %x) {
+; CHECK-LABEL: @fold_zext_sext_commuted(
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[X:%.*]] to i32
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X]] to i32
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[SEXT]], [[ZEXT]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %sext = sext i8 %x to i32
+  %zext = zext i8 %x to i32
+  %or = or i32 %sext, %zext
+  ret i32 %or
+}
+
+define <4 x i32> @fold_zext_sext_vec(<4 x i16> %x) {
+; CHECK-LABEL: @fold_zext_sext_vec(
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext <4 x i16> [[X:%.*]] to <4 x i32>
+; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i16> [[X]] to <4 x i32>
+; CHECK-NEXT:    [[R:%.*]] = or <4 x i32> [[ZEXT]], [[SEXT]]
+; CHECK-NEXT:    ret <4 x i32> [[R]]
+;
+  %zext = zext <4 x i16> %x to <4 x i32>
+  %sext = sext <4 x i16> %x to <4 x i32>
+  %or = or <4 x i32> %zext, %sext
+  ret <4 x i32> %or
+}
+
+define i32 @multi_use_fold_zext_sext_1(i8 %x) {
+; CHECK-LABEL: @multi_use_fold_zext_sext_1(
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    call void @use32(i32 [[ZEXT]])
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[ZEXT]], [[SEXT]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %zext = zext i8 %x to i32
+  %sext = sext i8 %x to i32
+  call void @use32(i32 %zext)
+  %or = or i32 %zext, %sext
+  ret i32 %or
+}
+
+define i32 @multi_use_fold_zext_sext_2(i8 %x) {
+; CHECK-LABEL: @multi_use_fold_zext_sext_2(
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    call void @use32(i32 [[SEXT]])
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[ZEXT]], [[SEXT]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %zext = zext i8 %x to i32
+  %sext = sext i8 %x to i32
+  call void @use32(i32 %sext)
+  %or = or i32 %zext, %sext
+  ret i32 %or
+}
+
+define i32 @neg_different_sources(i8 %x, i8 %y) {
+; CHECK-LABEL: @neg_different_sources(
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[Y:%.*]] to i32
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[ZEXT]], [[SEXT]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %zext = zext i8 %x to i32
+  %sext = sext i8 %y to i32
+  %or = or i32 %zext, %sext
+  ret i32 %or
+}
+
+define i32 @neg_zext_only(i8 %x, i8 %y) {
+; CHECK-LABEL: @neg_zext_only(
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = zext i8 [[R1]] to i32
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %z0 = zext i8 %x to i32
+  %z1 = zext i8 %y to i32
+  %or = or i32 %z0, %z1
+  ret i32 %or
+}
+
+define i32 @neg_sext_only(i8 %x, i8 %y) {
+; CHECK-LABEL: @neg_sext_only(
+; CHECK-NEXT:    [[R1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = sext i8 [[R1]] to i32
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %s0 = sext i8 %x to i32
+  %s1 = sext i8 %y to i32
+  %or = or i32 %s0, %s1
+  ret i32 %or
+}
+
+define i32 @neg_equal_but_distinct(i8 %x) {
+; CHECK-LABEL: @neg_equal_but_distinct(
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i32
+; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[R:%.*]] = or i32 [[ZEXT]], [[SEXT]]
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %y = add i8 %x, 0
+  %zext = zext i8 %x to i32
+  %sext = sext i8 %y to i32
+  %or = or i32 %zext, %sext
+  ret i32 %or
+}



More information about the llvm-commits mailing list