[llvm-branch-commits] [llvm] release/18.x: [GVN] Drop nsw/nuw flags when replacing the result of a with.overflow intrinsic with a overflowing binary operator (#82935) (PR #82965)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 26 00:03:00 PST 2024
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/82965
Backport 892b4beeac50920e630f10905b2916295e2eb6d8
Requested by: @dtcxzyw
>From 14fb01ef0e443c04d718466608e62dbbc3cfd9ce Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 26 Feb 2024 15:55:56 +0800
Subject: [PATCH] [GVN] Drop nsw/nuw flags when replacing the result of a
with.overflow intrinsic with a overflowing binary operator (#82935)
Alive2: https://alive2.llvm.org/ce/z/gyL7mn
Fixes https://github.com/llvm/llvm-project/issues/82884.
(cherry picked from commit 892b4beeac50920e630f10905b2916295e2eb6d8)
---
llvm/lib/Transforms/Utils/Local.cpp | 8 +++++++-
llvm/test/Transforms/GVN/pr82884.ll | 21 +++++++++++++++++++++
2 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Transforms/GVN/pr82884.ll
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 459e3d98059283..a1c6bbc52fd05e 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3369,11 +3369,17 @@ void llvm::patchReplacementInstruction(Instruction *I, Value *Repl) {
// Patch the replacement so that it is not more restrictive than the value
// being replaced.
+ WithOverflowInst *UnusedWO;
+ // When replacing the result of a llvm.*.with.overflow intrinsic with a
+ // overflowing binary operator, nuw/nsw flags may no longer hold.
+ if (isa<OverflowingBinaryOperator>(ReplInst) &&
+ match(I, m_ExtractValue<0>(m_WithOverflowInst(UnusedWO))))
+ ReplInst->dropPoisonGeneratingFlags();
// Note that if 'I' is a load being replaced by some operation,
// for example, by an arithmetic operation, then andIRFlags()
// would just erase all math flags from the original arithmetic
// operation, which is clearly not wanted and not needed.
- if (!isa<LoadInst>(I))
+ else if (!isa<LoadInst>(I))
ReplInst->andIRFlags(I);
// FIXME: If both the original and replacement value are part of the
diff --git a/llvm/test/Transforms/GVN/pr82884.ll b/llvm/test/Transforms/GVN/pr82884.ll
new file mode 100644
index 00000000000000..71abafda60d93d
--- /dev/null
+++ b/llvm/test/Transforms/GVN/pr82884.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S -passes=gvn < %s | FileCheck %s
+
+; Make sure nsw/nuw flags are dropped.
+
+define i32 @pr82884(i32 %x) {
+; CHECK-LABEL: define i32 @pr82884(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[X]], [[X]]
+; CHECK-NEXT: call void @use(i32 [[MUL]])
+; CHECK-NEXT: [[MUL2:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[X]], i32 [[X]])
+; CHECK-NEXT: ret i32 [[MUL]]
+;
+ %mul = mul nsw nuw i32 %x, %x
+ call void @use(i32 %mul)
+ %mul2 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %x, i32 %x)
+ %ret = extractvalue { i32, i1 } %mul2, 0
+ ret i32 %ret
+}
+
+declare void @use(i32)
More information about the llvm-branch-commits
mailing list