[llvm] [X86] Added support for 16bit LEA instruction (PR #122102)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 8 08:13:46 PST 2025
https://github.com/JaydeepChauhan14 updated https://github.com/llvm/llvm-project/pull/122102
>From f9cf1159bdf3c12a610bc07d6b0860496f9659bc Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Wed, 8 Jan 2025 20:33:55 +0800
Subject: [PATCH 1/2] [X86] Added support for 16bit LEA instruction
---
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 37 ++++++++++++++++++++
llvm/lib/Target/X86/X86InstrArithmetic.td | 6 ++++
llvm/lib/Target/X86/X86InstrFragments.td | 5 +++
llvm/lib/Target/X86/X86InstrOperands.td | 6 ++++
llvm/test/CodeGen/X86/16bit-lea.ll | 14 ++++++++
llvm/utils/TableGen/X86RecognizableInstr.cpp | 2 ++
6 files changed, 70 insertions(+)
create mode 100644 llvm/test/CodeGen/X86/16bit-lea.ll
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)
>From 71c70f206d6ca208f40e45a0b2acc8d520d8563f Mon Sep 17 00:00:00 2001
From: Chauhan Jaydeep Ashwinbhai <chauhan.jaydeep.ashwinbhai at intel.com>
Date: Thu, 9 Jan 2025 00:13:14 +0800
Subject: [PATCH 2/2] Addressed the testcase review comments
---
llvm/test/CodeGen/X86/{16bit-lea.ll => lea-16bit.ll} | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
rename llvm/test/CodeGen/X86/{16bit-lea.ll => lea-16bit.ll} (73%)
diff --git a/llvm/test/CodeGen/X86/16bit-lea.ll b/llvm/test/CodeGen/X86/lea-16bit.ll
similarity index 73%
rename from llvm/test/CodeGen/X86/16bit-lea.ll
rename to llvm/test/CodeGen/X86/lea-16bit.ll
index 049b216c313fa8..c06fa91b6fe721 100644
--- a/llvm/test/CodeGen/X86/16bit-lea.ll
+++ b/llvm/test/CodeGen/X86/lea-16bit.ll
@@ -1,13 +1,12 @@
; 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 {
+define i16 @lea16bit(i16 %in) {
; CHECK-LABEL: lea16bit:
-; CHECK: # %bb.0: # %entry
+; CHECK: # %bb.0:
; 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
More information about the llvm-commits
mailing list