Skip to content

Commit a03eeb0

Browse files
authored
[SelectionDAG][X86] Add a NoWrap flag to SelectionDAG::isAddLike. NFC (#90681)
If this flag is set, Xor will not be considered AddLike. If an Xor were treated as an Add it may wrap. If we can prove there would be no carry out and thus no wrap, the Xor would be turned into a disjoint Or by DAGCombine. Use this new flag to fix a bug in X86 where an Xor is incorrectly being treated as an NUWAdd. Fixes #90668.
1 parent 85f28cf commit a03eeb0

File tree

4 files changed

+8
-6
lines changed

4 files changed

+8
-6
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,8 +2083,9 @@ class SelectionDAG {
20832083
/// Return true if the specified operand is an ISD::OR or ISD::XOR node
20842084
/// that can be treated as an ISD::ADD node.
20852085
/// or(x,y) == add(x,y) iff haveNoCommonBitsSet(x,y)
2086-
/// xor(x,y) == add(x,y) iff isMinSignedConstant(y)
2087-
bool isADDLike(SDValue Op) const;
2086+
/// xor(x,y) == add(x,y) iff isMinSignedConstant(y) && !NoWrap
2087+
/// If \p NoWrap is true, this will not match ISD::XOR.
2088+
bool isADDLike(SDValue Op, bool NoWrap = false) const;
20882089

20892090
/// Return true if the specified operand is an ISD::ADD with a ConstantSDNode
20902091
/// on the right-hand side, or if it is an ISD::OR with a ConstantSDNode that

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5231,13 +5231,13 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
52315231
return true;
52325232
}
52335233

5234-
bool SelectionDAG::isADDLike(SDValue Op) const {
5234+
bool SelectionDAG::isADDLike(SDValue Op, bool NoWrap) const {
52355235
unsigned Opcode = Op.getOpcode();
52365236
if (Opcode == ISD::OR)
52375237
return Op->getFlags().hasDisjoint() ||
52385238
haveNoCommonBitsSet(Op.getOperand(0), Op.getOperand(1));
52395239
if (Opcode == ISD::XOR)
5240-
return isMinSignedConstant(Op.getOperand(1));
5240+
return !NoWrap && isMinSignedConstant(Op.getOperand(1));
52415241
return false;
52425242
}
52435243

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2353,7 +2353,7 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
23532353
SDValue Src = N.getOperand(0);
23542354
unsigned SrcOpc = Src.getOpcode();
23552355
if (((SrcOpc == ISD::ADD && Src->getFlags().hasNoUnsignedWrap()) ||
2356-
CurDAG->isADDLike(Src)) &&
2356+
CurDAG->isADDLike(Src, /*NoWrap=*/true)) &&
23572357
Src.hasOneUse()) {
23582358
if (CurDAG->isBaseWithConstantOffset(Src)) {
23592359
SDValue AddSrc = Src.getOperand(0);

llvm/test/CodeGen/X86/pr90668.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
define i64 @off(i8 signext %a) {
55
; CHECK-LABEL: off:
66
; CHECK: # %bb.0: # %entry
7+
; CHECK-NEXT: addb $-128, %dil
78
; CHECK-NEXT: movzbl %dil, %eax
8-
; CHECK-NEXT: leal 1024(,%rax,8), %eax
9+
; CHECK-NEXT: shll $3, %eax
910
; CHECK-NEXT: retq
1011
entry:
1112
%add = xor i8 %a, -128

0 commit comments

Comments
 (0)