[llvm] [X86] Added support for 16bit LEA instruction (PR #122102)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 8 04:37:04 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-tablegen
Author: None (JaydeepChauhan14)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/122102.diff
6 Files Affected:
- (modified) llvm/lib/Target/X86/X86ISelDAGToDAG.cpp (+37)
- (modified) llvm/lib/Target/X86/X86InstrArithmetic.td (+6)
- (modified) llvm/lib/Target/X86/X86InstrFragments.td (+5)
- (modified) llvm/lib/Target/X86/X86InstrOperands.td (+6)
- (added) llvm/test/CodeGen/X86/16bit-lea.ll (+14)
- (modified) llvm/utils/TableGen/X86RecognizableInstr.cpp (+2)
``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index 9b340a778b36ad..7f33b40503c2c8 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -226,6 +226,8 @@ namespace {
bool selectLEAAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
+ bool selectLEA64_16Addr(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);
@@ -3054,6 +3056,41 @@ bool X86DAGToDAGISel::selectMOV64Imm32(SDValue N, SDValue &Imm) {
return !TM.isLargeGlobalValue(GV);
}
+bool X86DAGToDAGISel::selectLEA64_16Addr(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;
+
+ auto *RN = dyn_cast<RegisterSDNode>(Base);
+ if (RN && RN->getReg() == 0)
+ Base = CurDAG->getRegister(0, MVT::i64);
+ else if (Base.getValueType() == MVT::i16 && !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_16bit, DL, MVT::i64, ImplDef,
+ Base);
+ }
+
+ RN = dyn_cast<RegisterSDNode>(Index);
+ if (RN && RN->getReg() == 0)
+ Index = CurDAG->getRegister(0, MVT::i64);
+ else {
+ assert(Index.getValueType() == MVT::i16 &&
+ "Expect to be extending 16-bit registers for use in LEA");
+ SDValue ImplDef =
+ SDValue(CurDAG->getMachineNode(X86::IMPLICIT_DEF, DL, MVT::i64), 0);
+ Index = CurDAG->getTargetInsertSubreg(X86::sub_16bit, DL, MVT::i64, ImplDef,
+ Index);
+ }
+
+ return true;
+}
+
bool X86DAGToDAGISel::selectLEA64_32Addr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment) {
diff --git a/llvm/lib/Target/X86/X86InstrArithmetic.td b/llvm/lib/Target/X86/X86InstrArithmetic.td
index 16ca2882a84daf..a72fc02e1ba523 100644
--- a/llvm/lib/Target/X86/X86InstrArithmetic.td
+++ b/llvm/lib/Target/X86/X86InstrArithmetic.td
@@ -25,6 +25,12 @@ let SchedRW = [WriteLEA] in {
[(set GR32:$dst, lea32addr:$src)]>,
OpSize32, Requires<[Not64BitMode]>;
+ def LEA64_16r : I<0x8D, MRMSrcMem, (outs GR16:$dst), (ins lea64_16mem:$src),
+ "lea{w}\t{$src|$dst}, {$dst|$src}",
+ [(set GR16:$dst, lea64_16addr:$src)]>,
+ OpSize16,
+ Requires<[In64BitMode]>;
+
def LEA64_32r : I<0x8D, MRMSrcMem,
(outs GR32:$dst), (ins lea64_32mem:$src),
"lea{l}\t{$src|$dst}, {$dst|$src}",
diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td
index ea7af893ce103f..ada4c29da4a97f 100644
--- a/llvm/lib/Target/X86/X86InstrFragments.td
+++ b/llvm/lib/Target/X86/X86InstrFragments.td
@@ -357,6 +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 16-bit LEAs can use RIP-relative addressing.
+def lea64_16addr : ComplexPattern<i16, 5, "selectLEA64_16Addr",
+ [add, sub, mul, X86mul_imm, shl, or, xor,
+ frameindex, X86WrapperRIP],
+ []>;
// 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,
diff --git a/llvm/lib/Target/X86/X86InstrOperands.td b/llvm/lib/Target/X86/X86InstrOperands.td
index 2102cb4b6b5b73..4bf31c115e635e 100644
--- a/llvm/lib/Target/X86/X86InstrOperands.td
+++ b/llvm/lib/Target/X86/X86InstrOperands.td
@@ -461,6 +461,12 @@ def i64u8imm : Operand<i64> {
let OperandType = "OPERAND_IMMEDIATE";
}
+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/16bit-lea.ll b/llvm/test/CodeGen/X86/16bit-lea.ll
new file mode 100644
index 00000000000000..049b216c313fa8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/16bit-lea.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+ndd | FileCheck %s --check-prefixes=CHECK
+
+define dso_local signext range(i16 1, 0) i16 @lea16bit(i16 noundef signext %in) local_unnamed_addr #0 {
+; CHECK-LABEL: lea16bit:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
+; CHECK-NEXT: leaw 1(%rdi,%rdi), %ax
+; CHECK-NEXT: retq
+entry:
+ %shl = shl i16 %in, 1
+ %or = or disjoint i16 %shl, 1
+ ret i16 %or
+}
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index c6cd3da13646a6..af16b3782195b0 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -1096,6 +1096,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("brtarget16", TYPE_REL)
TYPE("brtarget8", TYPE_REL)
TYPE("f80mem", TYPE_M)
+ TYPE("lea64_16mem", TYPE_M)
TYPE("lea64_32mem", TYPE_M)
TYPE("lea64mem", TYPE_M)
TYPE("VR64", TYPE_MM64)
@@ -1367,6 +1368,7 @@ RecognizableInstr::memoryEncodingFromString(const std::string &s,
ENCODING("i512mem_GR32", ENCODING_RM)
ENCODING("i512mem_GR64", ENCODING_RM)
ENCODING("f80mem", ENCODING_RM)
+ ENCODING("lea64_16mem", ENCODING_RM)
ENCODING("lea64_32mem", ENCODING_RM)
ENCODING("lea64mem", ENCODING_RM)
ENCODING("anymem", ENCODING_RM)
``````````
</details>
https://github.com/llvm/llvm-project/pull/122102
More information about the llvm-commits
mailing list