[llvm] [LICM] Drop NSW/NUW flags on reassociated integer Mul instructions (PR #85645)

Danila Malyutin via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 18 07:11:55 PDT 2024


https://github.com/danilaml created https://github.com/llvm/llvm-project/pull/85645

After reassociation NSW/NUW may no longer be valid.

Fixes #85448

>From 90d65b2106fd428702a05820f45382bbcd6e0c5a Mon Sep 17 00:00:00 2001
From: Danila Malyutin <dmalyutin at azul.com>
Date: Mon, 18 Mar 2024 18:06:43 +0400
Subject: [PATCH] [LICM] Drop NSW/NUW flags on reassociated integer Mul
 instructions

After reassociation NSW/NUW may no longer be valid.

Fixes #85448
---
 llvm/lib/Transforms/Scalar/LICM.cpp  |  5 ++++-
 llvm/test/Transforms/LICM/pr85448.ll | 29 ++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/LICM/pr85448.ll

diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 40bc16f9b57516..53c6026bfb20df 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2741,13 +2741,16 @@ static bool hoistMulAddAssociation(Instruction &I, Loop &L,
   IRBuilder<> Builder(Preheader->getTerminator());
   for (auto *U : Changes) {
     assert(L.isLoopInvariant(U->get()));
-    Instruction *Ins = cast<Instruction>(U->getUser());
+    BinaryOperator *Ins = cast<BinaryOperator>(U->getUser());
     Value *Mul;
     if (I.getType()->isIntOrIntVectorTy())
       Mul = Builder.CreateMul(U->get(), Factor, "factor.op.mul");
     else
       Mul = Builder.CreateFMulFMF(U->get(), Factor, Ins, "factor.op.fmul");
     U->set(Mul);
+    // We cannot guarantee the validity of NSW/NUW flags after reassociation.
+    Ins->setHasNoSignedWrap(false);
+    Ins->setHasNoUnsignedWrap(false);
   }
   I.replaceAllUsesWith(VariantOp);
   eraseInstruction(I, SafetyInfo, MSSAU);
diff --git a/llvm/test/Transforms/LICM/pr85448.ll b/llvm/test/Transforms/LICM/pr85448.ll
new file mode 100644
index 00000000000000..acff3766e7fca3
--- /dev/null
+++ b/llvm/test/Transforms/LICM/pr85448.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -passes='loop-mssa(licm)' -S %s | FileCheck %s
+
+; Check that NSW/NUW flags are correctly dropped after reassociation
+
+define void @test(i32 %a) {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[VAL:%.*]] = phi i32 [ 1, [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[VAL]], [[A]]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[TMP0]], -589824
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 null(i32 [[TMP1]])
+; CHECK-NEXT:    br label [[LOOP]]
+;
+entry:
+  br label %loop
+
+loop:                              ; preds = %loop, %entry
+  %val = phi i32 [ 1, %loop ], [ 0, %entry ]
+  %0 = or i32 %val, %a
+  %1 = mul nuw i32 %0, 65536
+  %sext = mul nsw i32 %1, -9
+  %2 = call i32 null(i32 %sext)
+  br label %loop
+}
+



More information about the llvm-commits mailing list