[llvm] cf05b6e - [X86] Added support for 8 and 16bit LEA instructions (#122102)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 3 16:12:20 PST 2025
Author: JaydeepChauhan14
Date: 2025-03-04T08:12:17+08:00
New Revision: cf05b6e25ac8dcbf6e0ea1524d86bc6d190bf8c0
URL: https://github.com/llvm/llvm-project/commit/cf05b6e25ac8dcbf6e0ea1524d86bc6d190bf8c0
DIFF: https://github.com/llvm/llvm-project/commit/cf05b6e25ac8dcbf6e0ea1524d86bc6d190bf8c0.diff
LOG: [X86] Added support for 8 and 16bit LEA instructions (#122102)
Added:
llvm/test/CodeGen/X86/lea-16bit.ll
llvm/test/CodeGen/X86/lea-8bit.ll
Modified:
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/lib/Target/X86/X86InstrArithmetic.td
llvm/lib/Target/X86/X86InstrFragments.td
llvm/lib/Target/X86/X86InstrOperands.td
llvm/utils/TableGen/X86RecognizableInstr.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index a7a0e84ba2b60..f1692b5417094 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -226,9 +226,8 @@ namespace {
bool selectLEAAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
- bool selectLEA64_32Addr(SDValue N, SDValue &Base,
- SDValue &Scale, SDValue &Index, SDValue &Disp,
- SDValue &Segment);
+ bool selectLEA64_Addr(SDValue N, SDValue &Base, SDValue &Scale,
+ SDValue &Index, SDValue &Disp, SDValue &Segment);
bool selectTLSADDRAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
@@ -3058,36 +3057,46 @@ bool X86DAGToDAGISel::selectMOV64Imm32(SDValue N, SDValue &Imm) {
return !TM.isLargeGlobalValue(GV);
}
-bool X86DAGToDAGISel::selectLEA64_32Addr(SDValue N, SDValue &Base,
- SDValue &Scale, SDValue &Index,
- SDValue &Disp, SDValue &Segment) {
+bool X86DAGToDAGISel::selectLEA64_Addr(SDValue N, SDValue &Base, SDValue &Scale,
+ SDValue &Index, SDValue &Disp,
+ SDValue &Segment) {
// Save the debug loc before calling selectLEAAddr, in case it invalidates N.
SDLoc DL(N);
if (!selectLEAAddr(N, Base, Scale, Index, Disp, Segment))
return false;
+ EVT BaseType = Base.getValueType();
+ unsigned SubReg;
+ if (BaseType == MVT::i8)
+ SubReg = X86::sub_8bit;
+ else if (BaseType == MVT::i16)
+ SubReg = X86::sub_16bit;
+ else
+ SubReg = X86::sub_32bit;
+
auto *RN = dyn_cast<RegisterSDNode>(Base);
if (RN && RN->getReg() == 0)
Base = CurDAG->getRegister(0, MVT::i64);
- else if (Base.getValueType() == MVT::i32 && !isa<FrameIndexSDNode>(Base)) {
+ else if ((BaseType == MVT::i8 || BaseType == MVT::i16 ||
+ BaseType == MVT::i32) &&
+ !isa<FrameIndexSDNode>(Base)) {
// Base could already be %rip, particularly in the x32 ABI.
SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, DL,
MVT::i64), 0);
- Base = CurDAG->getTargetInsertSubreg(X86::sub_32bit, DL, MVT::i64, ImplDef,
- Base);
+ Base = CurDAG->getTargetInsertSubreg(SubReg, DL, MVT::i64, ImplDef, Base);
}
+ EVT IndexType = Index.getValueType();
RN = dyn_cast<RegisterSDNode>(Index);
if (RN && RN->getReg() == 0)
Index = CurDAG->getRegister(0, MVT::i64);
else {
- assert(Index.getValueType() == MVT::i32 &&
- "Expect to be extending 32-bit registers for use in LEA");
+ assert((IndexType == BaseType) &&
+ "Expect to be extending 8/16/32-bit registers for use in LEA");
SDValue ImplDef = SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, DL,
MVT::i64), 0);
- Index = CurDAG->getTargetInsertSubreg(X86::sub_32bit, DL, MVT::i64, ImplDef,
- Index);
+ Index = CurDAG->getTargetInsertSubreg(SubReg, DL, MVT::i64, ImplDef, Index);
}
return true;
diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index 16ca2882a84da..f369c20c786c5 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -25,11 +25,25 @@ let SchedRW = [WriteLEA] in {
[(set GR32:$dst, lea32addr:$src)]>,
OpSize32, Requires<[Not64BitMode]>;
- def LEA64_32r : I<0x8D, MRMSrcMem,
- (outs GR32:$dst), (ins lea64_32mem:$src),
+ let Predicates = [HasNDD], isCodeGenOnly = 1 in {
+ def LEA64_8r : I<0x8D, MRMSrcMem, (outs GR8:$dst), (ins lea64_8mem:$src),
+ "lea{w}\t{$src|$dst}, {$dst|$src}",
+ [(set GR8:$dst, lea64_iaddr:$src)]>,
+ OpSize16,
+ Requires<[In64BitMode]>;
+
+ def LEA64_16r : I<0x8D, MRMSrcMem, (outs GR16:$dst), (ins lea64_16mem:$src),
+ "lea{w}\t{$src|$dst}, {$dst|$src}",
+ [(set GR16:$dst, lea64_iaddr:$src)]>,
+ OpSize16,
+ Requires<[In64BitMode]>;
+ }
+
+ def LEA64_32r : I<0x8D, MRMSrcMem, (outs GR32:$dst), (ins lea64_32mem:$src),
"lea{l}\t{$src|$dst}, {$dst|$src}",
- [(set GR32:$dst, lea64_32addr:$src)]>,
- OpSize32, Requires<[In64BitMode]>;
+ [(set GR32:$dst, lea64_iaddr:$src)]>,
+ OpSize32,
+ Requires<[In64BitMode]>;
let isReMaterializable = 1 in
def LEA64r : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td
index ddbc7c55a6113..a7ef72be9316f 100644
--- a/llvm/lib/Target/X86/X86InstrFragments.td
+++ b/llvm/lib/Target/X86/X86InstrFragments.td
@@ -357,11 +357,11 @@ def addr : ComplexPattern<iPTR, 5, "selectAddr">;
def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr",
[add, sub, mul, X86mul_imm, shl, or, xor, frameindex],
[]>;
-// In 64-bit mode 32-bit LEAs can use RIP-relative addressing.
-def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr",
- [add, sub, mul, X86mul_imm, shl, or, xor,
- frameindex, X86WrapperRIP],
- []>;
+// In 64-bit mode 8/16/32-bit LEAs can use RIP-relative addressing.
+def lea64_iaddr : ComplexPattern<iAny, 5, "selectLEA64_Addr",
+ [add, sub, mul, X86mul_imm, shl, or, xor,
+ frameindex, X86WrapperRIP],
+ []>;
def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr",
[tglobaltlsaddr], []>;
diff --git a/llvm/lib/Target/X86/X86InstrOperands.td b/llvm/lib/Target/X86/X86InstrOperands.td
index 4f427d6d9d72e..cefe4d7092478 100644
--- a/llvm/lib/Target/X86/X86InstrOperands.td
+++ b/llvm/lib/Target/X86/X86InstrOperands.td
@@ -456,6 +456,18 @@ def i64u8imm : Operand<i64> {
let OperandType = "OPERAND_IMMEDIATE";
}
+def lea64_8mem : Operand<i8> {
+ let PrintMethod = "printMemReference";
+ let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i8imm, SEGMENT_REG);
+ let ParserMatchClass = X86MemAsmOperand;
+}
+
+def lea64_16mem : Operand<i16> {
+ let PrintMethod = "printMemReference";
+ let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i16imm, SEGMENT_REG);
+ let ParserMatchClass = X86MemAsmOperand;
+}
+
def lea64_32mem : Operand<i32> {
let PrintMethod = "printMemReference";
let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG);
diff --git a/llvm/test/CodeGen/X86/lea-16bit.ll b/llvm/test/CodeGen/X86/lea-16bit.ll
new file mode 100644
index 0000000000000..cec29ab1da6ab
--- /dev/null
+++ b/llvm/test/CodeGen/X86/lea-16bit.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=NO-NDD
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+ndd | FileCheck %s --check-prefix=NDD
+
+define i16 @lea16bit(i16 %in) {
+; NO-NDD-LABEL: lea16bit:
+; NO-NDD: # %bb.0:
+; NO-NDD-NEXT: # kill: def $edi killed $edi def $rdi
+; NO-NDD-NEXT: leal 1(%rdi,%rdi), %eax
+; NO-NDD-NEXT: # kill: def $ax killed $ax killed $eax
+; NO-NDD-NEXT: retq
+;
+; NDD-LABEL: lea16bit:
+; NDD: # %bb.0:
+; NDD-NEXT: # kill: def $edi killed $edi def $rdi
+; NDD-NEXT: leaw 1(%rdi,%rdi), %ax
+; NDD-NEXT: retq
+ %shl = shl i16 %in, 1
+ %or = or i16 %shl, 1
+ ret i16 %or
+}
diff --git a/llvm/test/CodeGen/X86/lea-8bit.ll b/llvm/test/CodeGen/X86/lea-8bit.ll
new file mode 100644
index 0000000000000..b3c8f96bffaa9
--- /dev/null
+++ b/llvm/test/CodeGen/X86/lea-8bit.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=NO-NDD
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+ndd | FileCheck %s --check-prefix=NDD
+
+define i8 @lea8bit(i8 %in) {
+; NO-NDD-LABEL: lea8bit:
+; NO-NDD: # %bb.0:
+; NO-NDD-NEXT: # kill: def $edi killed $edi def $rdi
+; NO-NDD-NEXT: leal (%rdi,%rdi), %eax
+; NO-NDD-NEXT: incb %al
+; NO-NDD-NEXT: # kill: def $al killed $al killed $eax
+; NO-NDD-NEXT: retq
+;
+; NDD-LABEL: lea8bit:
+; NDD: # %bb.0:
+; NDD-NEXT: # kill: def $edi killed $edi def $rdi
+; NDD-NEXT: leaw 1(%rdi,%rdi), %al
+; NDD-NEXT: retq
+ %shl = shl i8 %in, 1
+ %or = or i8 %shl, 1
+ ret i8 %or
+}
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 607a6bd27c21f..003c8266c4785 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -1096,6 +1096,8 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("brtarget16", TYPE_REL)
TYPE("brtarget8", TYPE_REL)
TYPE("f80mem", TYPE_M)
+ TYPE("lea64_8mem", TYPE_M)
+ TYPE("lea64_16mem", TYPE_M)
TYPE("lea64_32mem", TYPE_M)
TYPE("lea64mem", TYPE_M)
TYPE("VR64", TYPE_MM64)
@@ -1364,6 +1366,8 @@ RecognizableInstr::memoryEncodingFromString(const std::string &s,
ENCODING("i512mem_GR32", ENCODING_RM)
ENCODING("i512mem_GR64", ENCODING_RM)
ENCODING("f80mem", ENCODING_RM)
+ ENCODING("lea64_8mem", ENCODING_RM)
+ ENCODING("lea64_16mem", ENCODING_RM)
ENCODING("lea64_32mem", ENCODING_RM)
ENCODING("lea64mem", ENCODING_RM)
ENCODING("anymem", ENCODING_RM)
More information about the llvm-commits
mailing list