Skip to content

Commit b4b3be7

Browse files
authored
[DAGCombiner] Teach SearchForAndLoads to handle an AND with 2 constant operands. (#142062)
If opaque constants are involved we can have an AND with 2 constant operands that hasn't been simplified. If this is the case, we need to modify at least one of the constants if it is out of range. Fixes #142004
1 parent 0a75d8e commit b4b3be7

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6812,8 +6812,9 @@ bool DAGCombiner::SearchForAndLoads(SDNode *N,
68126812

68136813
// Some constants may need fixing up later if they are too large.
68146814
if (auto *C = dyn_cast<ConstantSDNode>(Op)) {
6815-
if ((N->getOpcode() == ISD::OR || N->getOpcode() == ISD::XOR) &&
6816-
!C->getAPIntValue().isSubsetOf(Mask->getAPIntValue()))
6815+
assert(ISD::isBitwiseLogicOp(N->getOpcode()) &&
6816+
"Expected bitwise logic operation");
6817+
if (!C->getAPIntValue().isSubsetOf(Mask->getAPIntValue()))
68176818
NodesWithConsts.insert(N);
68186819
continue;
68196820
}
@@ -6927,7 +6928,13 @@ bool DAGCombiner::BackwardsPropagateMask(SDNode *N) {
69276928
SDValue Op0 = LogicN->getOperand(0);
69286929
SDValue Op1 = LogicN->getOperand(1);
69296930

6930-
if (isa<ConstantSDNode>(Op0))
6931+
// We only need to fix AND if both inputs are constants. And we only need
6932+
// to fix one of the constants.
6933+
if (LogicN->getOpcode() == ISD::AND &&
6934+
(!isa<ConstantSDNode>(Op0) || !isa<ConstantSDNode>(Op1)))
6935+
continue;
6936+
6937+
if (isa<ConstantSDNode>(Op0) && LogicN->getOpcode() != ISD::AND)
69316938
Op0 =
69326939
DAG.getNode(ISD::AND, SDLoc(Op0), Op0.getValueType(), Op0, MaskOp);
69336940

llvm/test/CodeGen/RISCV/pr142004.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -mtriple=riscv64 | FileCheck %s
3+
4+
@f = global i64 0, align 8
5+
@d = global i64 0, align 8
6+
@e = global i32 0, align 8
7+
8+
define i32 @foo(i32 %x) {
9+
; CHECK-LABEL: foo:
10+
; CHECK: # %bb.0: # %entry
11+
; CHECK-NEXT: lui a1, %hi(f)
12+
; CHECK-NEXT: lui a2, %hi(d)
13+
; CHECK-NEXT: lbu a1, %lo(f)(a1)
14+
; CHECK-NEXT: lhu a2, %lo(d)(a2)
15+
; CHECK-NEXT: slli a0, a0, 48
16+
; CHECK-NEXT: srli a3, a0, 48
17+
; CHECK-NEXT: xori a0, a1, 255
18+
; CHECK-NEXT: or a0, a0, a2
19+
; CHECK-NEXT: lui a1, %hi(e)
20+
; CHECK-NEXT: sw a3, %lo(e)(a1)
21+
; CHECK-NEXT: ret
22+
entry:
23+
%1 = load i64, ptr @f, align 8
24+
%conv1 = and i64 %1, 255
25+
%conv2 = xor i64 %conv1, 255
26+
%2 = load i64, ptr @d, align 8
27+
%or = or i64 %conv2, %2
28+
%conv3 = trunc i64 %or to i32
29+
%conv4 = and i32 %conv3, 65535
30+
%and = and i32 %x, 65535
31+
store i32 %and, ptr @e
32+
ret i32 %conv4
33+
}

0 commit comments

Comments
 (0)