[llvm] [IR] Add support for trunc's nuw/nsw flags in `copyIRFlags` (PR #89353)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 19 01:17:53 PDT 2024


https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/89353

This patch fixes https://github.com/llvm/llvm-project/pull/85592#issuecomment-2065865020.

I found this while fixing flag propagation in my ["vectorizer"](https://github.com/dtcxzyw/llvm-codegen-benchmark/blob/main/vectorize.cpp).


>From 561bdef1ad5332b23741f528e9e2afbe0d0c7eaa Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 19 Apr 2024 15:53:00 +0800
Subject: [PATCH 1/2] [IR] Add pre-commit tests. NFC.

---
 llvm/test/Transforms/Scalarizer/basic.ll | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/llvm/test/Transforms/Scalarizer/basic.ll b/llvm/test/Transforms/Scalarizer/basic.ll
index 87a70ccd3fc7c5..ceb83a4c4d4e2e 100644
--- a/llvm/test/Transforms/Scalarizer/basic.ll
+++ b/llvm/test/Transforms/Scalarizer/basic.ll
@@ -283,13 +283,13 @@ end:
 define <4 x float> @f6(<4 x float> %x) {
 ; CHECK-LABEL: @f6(
 ; CHECK-NEXT:    [[X_I0:%.*]] = extractelement <4 x float> [[X:%.*]], i64 0
-; CHECK-NEXT:    [[RES_I0:%.*]] = fadd float [[X_I0]], 1.000000e+00, !fpmath !9
+; CHECK-NEXT:    [[RES_I0:%.*]] = fadd float [[X_I0]], 1.000000e+00, !fpmath [[META9:![0-9]+]]
 ; CHECK-NEXT:    [[X_I1:%.*]] = extractelement <4 x float> [[X]], i64 1
-; CHECK-NEXT:    [[RES_I1:%.*]] = fadd float [[X_I1]], 2.000000e+00, !fpmath !9
+; CHECK-NEXT:    [[RES_I1:%.*]] = fadd float [[X_I1]], 2.000000e+00, !fpmath [[META9]]
 ; CHECK-NEXT:    [[X_I2:%.*]] = extractelement <4 x float> [[X]], i64 2
-; CHECK-NEXT:    [[RES_I2:%.*]] = fadd float [[X_I2]], 3.000000e+00, !fpmath !9
+; CHECK-NEXT:    [[RES_I2:%.*]] = fadd float [[X_I2]], 3.000000e+00, !fpmath [[META9]]
 ; CHECK-NEXT:    [[X_I3:%.*]] = extractelement <4 x float> [[X]], i64 3
-; CHECK-NEXT:    [[RES_I3:%.*]] = fadd float [[X_I3]], 4.000000e+00, !fpmath !9
+; CHECK-NEXT:    [[RES_I3:%.*]] = fadd float [[X_I3]], 4.000000e+00, !fpmath [[META9]]
 ; CHECK-NEXT:    [[RES_UPTO0:%.*]] = insertelement <4 x float> poison, float [[RES_I0]], i64 0
 ; CHECK-NEXT:    [[RES_UPTO1:%.*]] = insertelement <4 x float> [[RES_UPTO0]], float [[RES_I1]], i64 1
 ; CHECK-NEXT:    [[RES_UPTO2:%.*]] = insertelement <4 x float> [[RES_UPTO1]], float [[RES_I2]], i64 2
@@ -865,6 +865,20 @@ define <2 x float> @f25(<2 x float> %src) {
   ret <2 x float> %mul
 }
 
+define <2 x i8> @test_copy_trunc_flags(<2 x i32> %src) {
+; CHECK-LABEL: @test_copy_trunc_flags(
+; CHECK-NEXT:    [[SRC_I0:%.*]] = extractelement <2 x i32> [[SRC:%.*]], i64 0
+; CHECK-NEXT:    [[TRUNC_I0:%.*]] = trunc i32 [[SRC_I0]] to i8
+; CHECK-NEXT:    [[SRC_I1:%.*]] = extractelement <2 x i32> [[SRC]], i64 1
+; CHECK-NEXT:    [[TRUNC_I1:%.*]] = trunc i32 [[SRC_I1]] to i8
+; CHECK-NEXT:    [[TRUNC_UPTO0:%.*]] = insertelement <2 x i8> poison, i8 [[TRUNC_I0]], i64 0
+; CHECK-NEXT:    [[TRUNC:%.*]] = insertelement <2 x i8> [[TRUNC_UPTO0]], i8 [[TRUNC_I1]], i64 1
+; CHECK-NEXT:    ret <2 x i8> [[TRUNC]]
+;
+  %trunc = trunc nuw nsw <2 x i32> %src to <2 x i8>
+  ret <2 x i8> %trunc
+}
+
 !0 = !{ !"root" }
 !1 = !{ !"set1", !0 }
 !2 = !{ !"set2", !0 }

>From 347881cc68673d0bc3ab429c38a1f9ba2d5d53ea Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 19 Apr 2024 15:54:10 +0800
Subject: [PATCH 2/2] [IR] Add support for trunc's nuw/nsw flags in
 `copyIRFlags`

---
 llvm/lib/IR/Instruction.cpp              | 7 +++++++
 llvm/test/Transforms/Scalarizer/basic.ll | 4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 6cab3c15124162..eb1c5f445eb8b5 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -636,6 +636,13 @@ void Instruction::copyIRFlags(const Value *V, bool IncludeWrapFlags) {
     }
   }
 
+  if (auto *TI = dyn_cast<TruncInst>(V)) {
+    if (isa<TruncInst>(this)) {
+      setHasNoSignedWrap(TI->hasNoSignedWrap());
+      setHasNoUnsignedWrap(TI->hasNoUnsignedWrap());
+    }
+  }
+
   // Copy the exact flag.
   if (auto *PE = dyn_cast<PossiblyExactOperator>(V))
     if (isa<PossiblyExactOperator>(this))
diff --git a/llvm/test/Transforms/Scalarizer/basic.ll b/llvm/test/Transforms/Scalarizer/basic.ll
index ceb83a4c4d4e2e..f57ec8d589821f 100644
--- a/llvm/test/Transforms/Scalarizer/basic.ll
+++ b/llvm/test/Transforms/Scalarizer/basic.ll
@@ -868,9 +868,9 @@ define <2 x float> @f25(<2 x float> %src) {
 define <2 x i8> @test_copy_trunc_flags(<2 x i32> %src) {
 ; CHECK-LABEL: @test_copy_trunc_flags(
 ; CHECK-NEXT:    [[SRC_I0:%.*]] = extractelement <2 x i32> [[SRC:%.*]], i64 0
-; CHECK-NEXT:    [[TRUNC_I0:%.*]] = trunc i32 [[SRC_I0]] to i8
+; CHECK-NEXT:    [[TRUNC_I0:%.*]] = trunc nuw nsw i32 [[SRC_I0]] to i8
 ; CHECK-NEXT:    [[SRC_I1:%.*]] = extractelement <2 x i32> [[SRC]], i64 1
-; CHECK-NEXT:    [[TRUNC_I1:%.*]] = trunc i32 [[SRC_I1]] to i8
+; CHECK-NEXT:    [[TRUNC_I1:%.*]] = trunc nuw nsw i32 [[SRC_I1]] to i8
 ; CHECK-NEXT:    [[TRUNC_UPTO0:%.*]] = insertelement <2 x i8> poison, i8 [[TRUNC_I0]], i64 0
 ; CHECK-NEXT:    [[TRUNC:%.*]] = insertelement <2 x i8> [[TRUNC_UPTO0]], i8 [[TRUNC_I1]], i64 1
 ; CHECK-NEXT:    ret <2 x i8> [[TRUNC]]



More information about the llvm-commits mailing list