Skip to content

Commit 53c81a8

Browse files
authored
[RISCV][SDAG] Fix constant narrowing when narrowing loads (#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.
1 parent 9d1a3fd commit 53c81a8

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6635,12 +6635,17 @@ bool DAGCombiner::BackwardsPropagateMask(SDNode *N) {
66356635
SDValue Op1 = LogicN->getOperand(1);
66366636

66376637
if (isa<ConstantSDNode>(Op0))
6638-
std::swap(Op0, Op1);
6638+
Op0 =
6639+
DAG.getNode(ISD::AND, SDLoc(Op0), Op0.getValueType(), Op0, MaskOp);
66396640

6640-
SDValue And = DAG.getNode(ISD::AND, SDLoc(Op1), Op1.getValueType(),
6641-
Op1, MaskOp);
6641+
if (isa<ConstantSDNode>(Op1))
6642+
Op1 =
6643+
DAG.getNode(ISD::AND, SDLoc(Op1), Op1.getValueType(), Op1, MaskOp);
66426644

6643-
DAG.UpdateNodeOperands(LogicN, Op0, And);
6645+
if (isa<ConstantSDNode>(Op0) && !isa<ConstantSDNode>(Op1))
6646+
std::swap(Op0, Op1);
6647+
6648+
DAG.UpdateNodeOperands(LogicN, Op0, Op1);
66446649
}
66456650

66466651
// Create narrow loads.

llvm/test/CodeGen/RISCV/pr68855.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc < %s -mtriple=riscv64 | FileCheck %s
3+
4+
define i16 @narrow_load(ptr %p1, ptr %p2) {
5+
; CHECK-LABEL: narrow_load:
6+
; CHECK: # %bb.0: # %entry
7+
; CHECK-NEXT: lhu a2, 0(a0)
8+
; CHECK-NEXT: lui a3, 2
9+
; CHECK-NEXT: addiw a3, a3, -1
10+
; CHECK-NEXT: xor a2, a2, a3
11+
; CHECK-NEXT: lui a4, 16
12+
; CHECK-NEXT: addi a4, a4, -1
13+
; CHECK-NEXT: xor a4, a3, a4
14+
; CHECK-NEXT: or a2, a2, a4
15+
; CHECK-NEXT: sw a2, 0(a1)
16+
; CHECK-NEXT: lhu a0, 0(a0)
17+
; CHECK-NEXT: and a0, a0, a3
18+
; CHECK-NEXT: ret
19+
entry:
20+
%bf.load = load i16, ptr %p1, align 2
21+
%bf.clear = and i16 %bf.load, 8191
22+
%not = xor i16 %bf.clear, -1
23+
%conv1 = zext i16 %not to i32
24+
store i32 %conv1, ptr %p2, align 4
25+
%bf.load2 = load i16, ptr %p1, align 2
26+
%bf.clear3 = and i16 %bf.load2, 8191
27+
ret i16 %bf.clear3
28+
}

0 commit comments

Comments
 (0)