Skip to content

Commit f6f7f4a

Browse files
committed
[X86] Reduce i64 to i32 when upper 33 bits are known zeros for add
1 parent acd264d commit f6f7f4a

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58070,8 +58070,28 @@ static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
5807058070
EVT VT = N->getValueType(0);
5807158071
SDValue Op0 = N->getOperand(0);
5807258072
SDValue Op1 = N->getOperand(1);
58073+
unsigned int Opcode = N->getOpcode();
5807358074
SDLoc DL(N);
5807458075

58076+
// Use a 32-bit add+zext if upper 33 bits known zero.
58077+
if (VT == MVT::i64 && Subtarget.is64Bit()) {
58078+
APInt HiMask = APInt::getHighBitsSet(64, 33);
58079+
if (DAG.MaskedValueIsZero(Op0, HiMask) &&
58080+
DAG.MaskedValueIsZero(Op1, HiMask)) {
58081+
SDValue LHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op0);
58082+
SDValue RHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
58083+
bool NSW = Op0->getFlags().hasNoSignedWrap();
58084+
bool NUW = Op0->getFlags().hasNoUnsignedWrap();
58085+
NSW = NSW & DAG.willNotOverflowAdd(true, LHS, RHS);
58086+
NUW = NUW & DAG.willNotOverflowAdd(false, LHS, RHS);
58087+
SDNodeFlags Flags;
58088+
Flags.setNoUnsignedWrap(NUW);
58089+
Flags.setNoSignedWrap(NSW);
58090+
SDValue Sum = DAG.getNode(Opcode, DL, MVT::i32, LHS, RHS, Flags);
58091+
return DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Sum);
58092+
}
58093+
}
58094+
5807558095
if (SDValue Select = pushAddIntoCmovOfConsts(N, DL, DAG, Subtarget))
5807658096
return Select;
5807758097

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86
3+
; RUN: llc < %s -mtriple=x86_64-linux -verify-machineinstrs | FileCheck %s --check-prefix=X64-LINUX
4+
; RUN: llc < %s -mtriple=x86_64-win32 | FileCheck %s --check-prefix=X64-WIN32
5+
6+
define i64 @test1(i16 %x) nounwind {
7+
; X86-LABEL: test1:
8+
; X86: # %bb.0: # %entry
9+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
10+
; X86-NEXT: addl $42, %eax
11+
; X86-NEXT: movzwl %ax, %eax
12+
; X86-NEXT: xorl %edx, %edx
13+
; X86-NEXT: retl
14+
;
15+
; X64-LINUX-LABEL: test1:
16+
; X64-LINUX: # %bb.0: # %entry
17+
; X64-LINUX-NEXT: addl $42, %edi
18+
; X64-LINUX-NEXT: movzwl %di, %eax
19+
; X64-LINUX-NEXT: retq
20+
;
21+
; X64-WIN32-LABEL: test1:
22+
; X64-WIN32: # %bb.0: # %entry
23+
; X64-WIN32-NEXT: # kill: def $cx killed $cx def $ecx
24+
; X64-WIN32-NEXT: addl $42, %ecx
25+
; X64-WIN32-NEXT: movzwl %cx, %eax
26+
; X64-WIN32-NEXT: retq
27+
entry:
28+
%add = add nuw nsw i16 %x, 42
29+
%conv = zext i16 %add to i64
30+
ret i64 %conv
31+
}

0 commit comments

Comments
 (0)