[llvm] [RISCV][SDAG] Fix constant narrowing when narrowing loads (PR #69015)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 13 10:52:24 PDT 2023


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

When narrowing logic ops(OR/XOR) with constant rhs, `DAGCombiner` will fixup the constant rhs node. 
It is incorrect when lhs is also a constant. For example, we will incorrectly replace `xor OpaqueConstant:i64<8191>, Constant:i64<-1>` with `xor (and OpaqueConstant:i64<8191>, Constant:i64<65535>), Constant:i64<-1>`.

Fixes #68855.


>From e00aa0d447cca6319acc498d3e871bf95f2d2d27 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 14 Oct 2023 01:18:42 +0800
Subject: [PATCH 1/2] [RISCV] Add pre-commit test for PR68855

---
 llvm/test/CodeGen/RISCV/pr68855.ll | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/pr68855.ll

diff --git a/llvm/test/CodeGen/RISCV/pr68855.ll b/llvm/test/CodeGen/RISCV/pr68855.ll
new file mode 100644
index 000000000000000..254e8c168f57474
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/pr68855.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc < %s -mtriple=riscv64 | FileCheck %s
+
+define i16 @narrow_load(ptr %p1, ptr %p2) {
+; CHECK-LABEL: narrow_load:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    lhu a2, 0(a0)
+; CHECK-NEXT:    not a2, a2
+; CHECK-NEXT:    lui a3, 2
+; CHECK-NEXT:    addiw a3, a3, -1
+; CHECK-NEXT:    li a4, -1
+; CHECK-NEXT:    xor a4, a4, a3
+; CHECK-NEXT:    or a2, a2, a4
+; CHECK-NEXT:    sw a2, 0(a1)
+; CHECK-NEXT:    lhu a0, 0(a0)
+; CHECK-NEXT:    and a0, a0, a3
+; CHECK-NEXT:    ret
+entry:
+  %bf.load = load i16, ptr %p1, align 2
+  %bf.clear = and i16 %bf.load, 8191
+  %not = xor i16 %bf.clear, -1
+  %conv1 = zext i16 %not to i32
+  store i32 %conv1, ptr %p2, align 4
+  %bf.load2 = load i16, ptr %p1, align 2
+  %bf.clear3 = and i16 %bf.load2, 8191
+  ret i16 %bf.clear3
+}

>From 55741181d03cf5be94e65970a3736da37323e0a5 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 14 Oct 2023 01:28:55 +0800
Subject: [PATCH 2/2] [RISCV][SDAG] Fix constant narrowing when narrowing loads

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 +++++++++----
 llvm/test/CodeGen/RISCV/pr68855.ll            |  7 ++++---
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 1021b07da1ac6c5..73438113651f55d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6635,12 +6635,17 @@ bool DAGCombiner::BackwardsPropagateMask(SDNode *N) {
       SDValue Op1 = LogicN->getOperand(1);
 
       if (isa<ConstantSDNode>(Op0))
-          std::swap(Op0, Op1);
+        Op0 =
+            DAG.getNode(ISD::AND, SDLoc(Op0), Op0.getValueType(), Op0, MaskOp);
 
-      SDValue And = DAG.getNode(ISD::AND, SDLoc(Op1), Op1.getValueType(),
-                                Op1, MaskOp);
+      if (isa<ConstantSDNode>(Op1))
+        Op1 =
+            DAG.getNode(ISD::AND, SDLoc(Op1), Op1.getValueType(), Op1, MaskOp);
 
-      DAG.UpdateNodeOperands(LogicN, Op0, And);
+      if (isa<ConstantSDNode>(Op0) && !isa<ConstantSDNode>(Op1))
+        std::swap(Op0, Op1);
+
+      DAG.UpdateNodeOperands(LogicN, Op0, Op1);
     }
 
     // Create narrow loads.
diff --git a/llvm/test/CodeGen/RISCV/pr68855.ll b/llvm/test/CodeGen/RISCV/pr68855.ll
index 254e8c168f57474..e9d1f6c2d1b2cc8 100644
--- a/llvm/test/CodeGen/RISCV/pr68855.ll
+++ b/llvm/test/CodeGen/RISCV/pr68855.ll
@@ -5,11 +5,12 @@ define i16 @narrow_load(ptr %p1, ptr %p2) {
 ; CHECK-LABEL: narrow_load:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    lhu a2, 0(a0)
-; CHECK-NEXT:    not a2, a2
 ; CHECK-NEXT:    lui a3, 2
 ; CHECK-NEXT:    addiw a3, a3, -1
-; CHECK-NEXT:    li a4, -1
-; CHECK-NEXT:    xor a4, a4, a3
+; CHECK-NEXT:    xor a2, a2, a3
+; CHECK-NEXT:    lui a4, 16
+; CHECK-NEXT:    addi a4, a4, -1
+; CHECK-NEXT:    xor a4, a3, a4
 ; CHECK-NEXT:    or a2, a2, a4
 ; CHECK-NEXT:    sw a2, 0(a1)
 ; CHECK-NEXT:    lhu a0, 0(a0)



More information about the llvm-commits mailing list