[llvm] [GISel] Don't preserve NSW flag when converting G_MUL of INT_MIN to G_SHL. (PR #111230)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 4 21:41:06 PDT 2024


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/111230

mul and shl have different meanings for the nsw flag. We need to drop it when converting a multiply by the minimum negative value.

>From 89cfd47db87570f00aba15dce6ba9e43c321da09 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 4 Oct 2024 21:28:59 -0700
Subject: [PATCH] [GISel] Don't preserve NSW flag when converting G_MUL of
 INT_MIN to G_SHL.

mul and shl have different meanings for the nsw flag. We need to
drop it when multiplying by minimum negative value.
---
 .../lib/CodeGen/GlobalISel/CombinerHelper.cpp |  2 +
 .../AArch64/GlobalISel/combine-mul-to-shl.mir | 48 +++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index c279289f9161bf..14e94d48bf8362 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -2036,6 +2036,8 @@ void CombinerHelper::applyCombineMulToShl(MachineInstr &MI,
   Observer.changingInstr(MI);
   MI.setDesc(MIB.getTII().get(TargetOpcode::G_SHL));
   MI.getOperand(2).setReg(ShiftCst.getReg(0));
+  if (ShiftVal == ShiftTy.getScalarSizeInBits() - 1)
+    MI.clearFlag(MachineInstr::MIFlag::NoSWrap);
   Observer.changedInstr(MI);
 }
 
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-mul-to-shl.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-mul-to-shl.mir
index 068f8e3beb9ed4..71eaf80f53ba4c 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-mul-to-shl.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-mul-to-shl.mir
@@ -96,3 +96,51 @@ body:             |
     $x0 = COPY %2(s64)
     RET_ReallyLR implicit-def $x0
 ...
+---
+name:            mul_to_shl_16_nuw_nsw
+alignment:       4
+tracksRegLiveness: true
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.0:
+    liveins: $x0
+    ; CHECK-LABEL: name: mul_to_shl_16_nuw_nsw
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
+    ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = nuw nsw G_SHL [[COPY]], [[C]](s64)
+    ; CHECK-NEXT: $x0 = COPY [[SHL]](s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit-def $x0
+    %0:_(s64) = COPY $x0
+    %1:_(s64) = G_CONSTANT i64 16
+    %2:_(s64) = nuw nsw G_MUL %0, %1(s64)
+    $x0 = COPY %2(s64)
+    RET_ReallyLR implicit-def $x0
+...
+---
+name:            mul_to_shl_int_min_nuw_nsw
+alignment:       4
+tracksRegLiveness: true
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.0:
+    liveins: $x0
+    ; CHECK-LABEL: name: mul_to_shl_int_min_nuw_nsw
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
+    ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(s64) = nuw G_SHL [[COPY]], [[C]](s64)
+    ; CHECK-NEXT: $x0 = COPY [[SHL]](s64)
+    ; CHECK-NEXT: RET_ReallyLR implicit-def $x0
+    %0:_(s64) = COPY $x0
+    %1:_(s64) = G_CONSTANT i64 -9223372036854775808
+    %2:_(s64) = nuw nsw G_MUL %0, %1(s64)
+    $x0 = COPY %2(s64)
+    RET_ReallyLR implicit-def $x0
+...



More information about the llvm-commits mailing list