[llvm] 14a027b - [X86][CodeGen] Support flags copy lowering for NDD ADC/SBB/RCL/RCR (#79280)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 26 00:49:49 PST 2024
Author: Shengchen Kan
Date: 2024-01-26T16:49:44+08:00
New Revision: 14a027b2b79b85f15dfa259c6b113bcf681d06a2
URL: https://github.com/llvm/llvm-project/commit/14a027b2b79b85f15dfa259c6b113bcf681d06a2
DIFF: https://github.com/llvm/llvm-project/commit/14a027b2b79b85f15dfa259c6b113bcf681d06a2.diff
LOG: [X86][CodeGen] Support flags copy lowering for NDD ADC/SBB/RCL/RCR (#79280)
Added:
llvm/test/CodeGen/X86/apx/flags-copy-lowering.mir
Modified:
llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
index aad839b83ee194e..af25b34fbab9954 100644
--- a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
+++ b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
@@ -165,30 +165,34 @@ static FlagArithMnemonic getMnemonicFromOpcode(unsigned Opcode) {
report_fatal_error("No support for lowering a copy into EFLAGS when used "
"by this instruction!");
+#define CASE_ND(OP) \
+ case X86::OP: \
+ case X86::OP##_ND:
+
#define LLVM_EXPAND_INSTR_SIZES(MNEMONIC, SUFFIX) \
- case X86::MNEMONIC##8##SUFFIX: \
- case X86::MNEMONIC##16##SUFFIX: \
- case X86::MNEMONIC##32##SUFFIX: \
- case X86::MNEMONIC##64##SUFFIX:
+ CASE_ND(MNEMONIC##8##SUFFIX) \
+ CASE_ND(MNEMONIC##16##SUFFIX) \
+ CASE_ND(MNEMONIC##32##SUFFIX) \
+ CASE_ND(MNEMONIC##64##SUFFIX)
#define LLVM_EXPAND_ADC_SBB_INSTR(MNEMONIC) \
LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rr) \
LLVM_EXPAND_INSTR_SIZES(MNEMONIC, rm) \
LLVM_EXPAND_INSTR_SIZES(MNEMONIC, mr) \
- case X86::MNEMONIC##8ri: \
- case X86::MNEMONIC##16ri8: \
- case X86::MNEMONIC##32ri8: \
- case X86::MNEMONIC##64ri8: \
- case X86::MNEMONIC##16ri: \
- case X86::MNEMONIC##32ri: \
- case X86::MNEMONIC##64ri32: \
- case X86::MNEMONIC##8mi: \
- case X86::MNEMONIC##16mi8: \
- case X86::MNEMONIC##32mi8: \
- case X86::MNEMONIC##64mi8: \
- case X86::MNEMONIC##16mi: \
- case X86::MNEMONIC##32mi: \
- case X86::MNEMONIC##64mi32: \
+ CASE_ND(MNEMONIC##8ri) \
+ CASE_ND(MNEMONIC##16ri8) \
+ CASE_ND(MNEMONIC##32ri8) \
+ CASE_ND(MNEMONIC##64ri8) \
+ CASE_ND(MNEMONIC##16ri) \
+ CASE_ND(MNEMONIC##32ri) \
+ CASE_ND(MNEMONIC##64ri32) \
+ CASE_ND(MNEMONIC##8mi) \
+ CASE_ND(MNEMONIC##16mi8) \
+ CASE_ND(MNEMONIC##32mi8) \
+ CASE_ND(MNEMONIC##64mi8) \
+ CASE_ND(MNEMONIC##16mi) \
+ CASE_ND(MNEMONIC##32mi) \
+ CASE_ND(MNEMONIC##64mi32) \
case X86::MNEMONIC##8i8: \
case X86::MNEMONIC##16i16: \
case X86::MNEMONIC##32i32: \
@@ -213,6 +217,7 @@ static FlagArithMnemonic getMnemonicFromOpcode(unsigned Opcode) {
return FlagArithMnemonic::RCR;
#undef LLVM_EXPAND_INSTR_SIZES
+#undef CASE_ND
case X86::SETB_C32r:
case X86::SETB_C64r:
@@ -806,7 +811,8 @@ void X86FlagsCopyLoweringPass::rewriteArithmetic(
// Insert an instruction that will set the flag back to the desired value.
Register TmpReg = MRI->createVirtualRegister(PromoteRC);
auto AddI =
- BuildMI(MBB, MI.getIterator(), MI.getDebugLoc(), TII->get(X86::ADD8ri))
+ BuildMI(MBB, MI.getIterator(), MI.getDebugLoc(),
+ TII->get(Subtarget->hasNDD() ? X86::ADD8ri_ND : X86::ADD8ri))
.addDef(TmpReg, RegState::Dead)
.addReg(CondReg)
.addImm(Addend);
diff --git a/llvm/test/CodeGen/X86/apx/flags-copy-lowering.mir b/llvm/test/CodeGen/X86/apx/flags-copy-lowering.mir
new file mode 100644
index 000000000000000..d6a9cda1dc81621
--- /dev/null
+++ b/llvm/test/CodeGen/X86/apx/flags-copy-lowering.mir
@@ -0,0 +1,168 @@
+# RUN: llc -run-pass x86-flags-copy-lowering -mattr=+ndd -verify-machineinstrs -o - %s | FileCheck %s
+# Lower various interesting copy patterns of EFLAGS without using LAHF/SAHF.
+
+--- |
+ target triple = "x86_64-unknown-unknown"
+
+ declare void @foo()
+
+ define void @test_adc(i64 %a, i64 %b) {
+ entry:
+ call void @foo()
+ ret void
+ }
+
+ define void @test_sbb(i64 %a, i64 %b) {
+ entry:
+ call void @foo()
+ ret void
+ }
+
+ define void @test_rcl(i64 %a, i64 %b) {
+ entry:
+ call void @foo()
+ ret void
+ }
+
+ define void @test_rcr(i64 %a, i64 %b) {
+ entry:
+ call void @foo()
+ ret void
+ }
+...
+---
+name: test_adc
+# CHECK-LABEL: name: test_adc
+liveins:
+ - { reg: '$rdi', virtual-reg: '%0' }
+ - { reg: '$rsi', virtual-reg: '%1' }
+body: |
+ bb.0:
+ liveins: $rdi, $rsi
+
+ %0:gr64 = COPY $rdi
+ %1:gr64 = COPY $rsi
+ %2:gr64 = ADD64rr_ND %0, %1, implicit-def $eflags
+ %3:gr64 = COPY $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+ ; CHECK: %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+
+ $eflags = COPY %3
+ %4:gr64 = ADC64ri32_ND %2:gr64, 42, implicit-def $eflags, implicit $eflags
+ %5:gr64 = ADC64ri32_ND %4:gr64, 42, implicit-def $eflags, implicit $eflags
+ ; CHECK-NOT: $eflags =
+ ; CHECK: dead %{{[^:]*}}:gr8 = ADD8ri_ND %[[CF_REG]], 255, implicit-def $eflags
+ ; CHECK-NEXT: %4:gr64 = ADC64ri32_ND %2, 42, implicit-def $eflags, implicit killed $eflags
+ ; CHECK-NEXT: %5:gr64 = ADC64ri32_ND %4, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
+ MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
+
+ RET 0
+
+...
+---
+name: test_sbb
+# CHECK-LABEL: name: test_sbb
+liveins:
+ - { reg: '$rdi', virtual-reg: '%0' }
+ - { reg: '$rsi', virtual-reg: '%1' }
+body: |
+ bb.0:
+ liveins: $rdi, $rsi
+
+ %0:gr64 = COPY $rdi
+ %1:gr64 = COPY $rsi
+ %2:gr64 = SUB64rr_ND %0, %1, implicit-def $eflags
+ %3:gr64 = COPY killed $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+ ; CHECK: %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+
+ $eflags = COPY %3
+ %4:gr64 = SBB64ri32_ND %2:gr64, 42, implicit-def $eflags, implicit killed $eflags
+ %5:gr64 = SBB64ri32_ND %4:gr64, 42, implicit-def dead $eflags, implicit killed $eflags
+ ; CHECK-NOT: $eflags =
+ ; CHECK: dead %{{[^:]*}}:gr8 = ADD8ri_ND %[[CF_REG]], 255, implicit-def $eflags
+ ; CHECK-NEXT: %4:gr64 = SBB64ri32_ND %2, 42, implicit-def $eflags, implicit killed $eflags
+ ; CHECK-NEXT: %5:gr64 = SBB64ri32_ND %4, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
+ MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
+
+ RET 0
+
+...
+---
+name: test_rcl
+# CHECK-LABEL: name: test_rcl
+liveins:
+ - { reg: '$rdi', virtual-reg: '%0' }
+ - { reg: '$rsi', virtual-reg: '%1' }
+body: |
+ bb.0:
+ liveins: $rdi, $rsi
+
+ %0:gr64 = COPY $rdi
+ %1:gr64 = COPY $rsi
+ %2:gr64 = ADD64rr_ND %0, %1, implicit-def $eflags
+ %3:gr64 = COPY $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+ ; CHECK: %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+
+ $eflags = COPY %3
+ %4:gr64 = RCL64r1_ND %2:gr64, implicit-def $eflags, implicit $eflags
+ %5:gr64 = RCL64r1_ND %4:gr64, implicit-def $eflags, implicit $eflags
+ ; CHECK-NOT: $eflags =
+ ; CHECK: dead %{{[^:]*}}:gr8 = ADD8ri_ND %[[CF_REG]], 255, implicit-def $eflags
+ ; CHECK-NEXT: %4:gr64 = RCL64r1_ND %2, implicit-def $eflags, implicit killed $eflags
+ ; CHECK-NEXT: %5:gr64 = RCL64r1_ND %4, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
+ MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
+
+ RET 0
+
+...
+---
+name: test_rcr
+# CHECK-LABEL: name: test_rcr
+liveins:
+ - { reg: '$rdi', virtual-reg: '%0' }
+ - { reg: '$rsi', virtual-reg: '%1' }
+body: |
+ bb.0:
+ liveins: $rdi, $rsi
+
+ %0:gr64 = COPY $rdi
+ %1:gr64 = COPY $rsi
+ %2:gr64 = ADD64rr_ND %0, %1, implicit-def $eflags
+ %3:gr64 = COPY $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+ ; CHECK: %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
+ ; CHECK-NOT: COPY{{( killed)?}} $eflags
+
+ ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+ CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
+ ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+
+ $eflags = COPY %3
+ %4:gr64 = RCR64r1_ND %2:gr64, implicit-def $eflags, implicit $eflags
+ %5:gr64 = RCR64r1_ND %4:gr64, implicit-def $eflags, implicit $eflags
+ ; CHECK-NOT: $eflags =
+ ; CHECK: dead %{{[^:]*}}:gr8 = ADD8ri_ND %[[CF_REG]], 255, implicit-def $eflags
+ ; CHECK-NEXT: %4:gr64 = RCR64r1_ND %2, implicit-def $eflags, implicit killed $eflags
+ ; CHECK-NEXT: %5:gr64 = RCR64r1_ND %4, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
+ MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
+
+ RET 0
+
+...
More information about the llvm-commits
mailing list