[llvm] r303255 - [GlobalISel][X86] Support add i64 in IA32.
Igor Breger via llvm-commits
llvm-commits at lists.llvm.org
Wed May 17 05:48:09 PDT 2017
Author: ibreger
Date: Wed May 17 07:48:08 2017
New Revision: 303255
URL: http://llvm.org/viewvc/llvm-project?rev=303255&view=rev
Log:
[GlobalISel][X86] Support add i64 in IA32.
Summary: support G_UADDE instruction selection.
Reviewers: zvi, guyblank
Reviewed By: guyblank
Subscribers: rovka, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D33096
Added:
llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X32.mir
llvm/trunk/test/CodeGen/X86/GlobalISel/select-add-x32.mir
Modified:
llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
llvm/trunk/test/CodeGen/X86/GlobalISel/add-scalar.ll
llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-add.mir
Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=303255&r1=303254&r2=303255&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Wed May 17 07:48:08 2017
@@ -19,6 +19,7 @@
#include "X86Subtarget.h"
#include "X86TargetMachine.h"
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -72,6 +73,9 @@ private:
bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
+ bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI,
+ MachineFunction &MF) const;
+
const X86TargetMachine &TM;
const X86Subtarget &STI;
const X86InstrInfo &TII;
@@ -243,6 +247,8 @@ bool X86InstructionSelector::select(Mach
return true;
if (selectCmp(I, MRI, MF))
return true;
+ if (selectUadde(I, MRI, MF))
+ return true;
return false;
}
@@ -562,6 +568,66 @@ bool X86InstructionSelector::selectCmp(M
I.eraseFromParent();
return true;
+}
+
+bool X86InstructionSelector::selectUadde(MachineInstr &I,
+ MachineRegisterInfo &MRI,
+ MachineFunction &MF) const {
+ if (I.getOpcode() != TargetOpcode::G_UADDE)
+ return false;
+
+ const unsigned DstReg = I.getOperand(0).getReg();
+ const unsigned CarryOutReg = I.getOperand(1).getReg();
+ const unsigned Op0Reg = I.getOperand(2).getReg();
+ const unsigned Op1Reg = I.getOperand(3).getReg();
+ unsigned CarryInReg = I.getOperand(4).getReg();
+
+ const LLT DstTy = MRI.getType(DstReg);
+
+ if (DstTy != LLT::scalar(32))
+ return false;
+
+ // find CarryIn def instruction.
+ MachineInstr *Def = MRI.getVRegDef(CarryInReg);
+ while (Def->getOpcode() == TargetOpcode::G_TRUNC) {
+ CarryInReg = Def->getOperand(1).getReg();
+ Def = MRI.getVRegDef(CarryInReg);
+ }
+
+ unsigned Opcode;
+ if (Def->getOpcode() == TargetOpcode::G_UADDE) {
+ // carry set by prev ADD.
+
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), X86::EFLAGS)
+ .addReg(CarryInReg);
+
+ if (!RBI.constrainGenericRegister(CarryInReg, X86::GR32RegClass, MRI))
+ return false;
+
+ Opcode = X86::ADC32rr;
+ } else if (auto val = getConstantVRegVal(CarryInReg, MRI)) {
+ // carry is constant, support only 0.
+ if (*val != 0)
+ return false;
+
+ Opcode = X86::ADD32rr;
+ } else
+ return false;
+
+ MachineInstr &AddInst =
+ *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
+ .addReg(Op0Reg)
+ .addReg(Op1Reg);
+
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::COPY), CarryOutReg)
+ .addReg(X86::EFLAGS);
+
+ if (!constrainSelectedInstRegOperands(AddInst, TII, TRI, RBI) ||
+ !RBI.constrainGenericRegister(CarryOutReg, X86::GR32RegClass, MRI))
+ return false;
+
+ I.eraseFromParent();
+ return true;
}
InstructionSelector *
Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=303255&r1=303254&r2=303255&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Wed May 17 07:48:08 2017
@@ -59,6 +59,11 @@ void X86LegalizerInfo::setLegalizerInfo3
for (auto Ty : {s8, s16, s32})
setAction({BinOp, Ty}, Legal);
+ for (unsigned Op : {G_UADDE}) {
+ setAction({Op, s32}, Legal);
+ setAction({Op, 1, s1}, Legal);
+ }
+
for (unsigned MemOp : {G_LOAD, G_STORE}) {
for (auto Ty : {s8, s16, s32, p0})
setAction({MemOp, Ty}, Legal);
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/add-scalar.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/add-scalar.ll?rev=303255&r1=303254&r2=303255&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/add-scalar.ll (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/add-scalar.ll Wed May 17 07:48:08 2017
@@ -1,44 +1,94 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
+; RUN: llc -mtriple=i386-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
define i64 @test_add_i64(i64 %arg1, i64 %arg2) {
-; ALL-LABEL: test_add_i64:
-; ALL: # BB#0:
-; ALL-NEXT: leaq (%rsi,%rdi), %rax
-; ALL-NEXT: retq
+; X64-LABEL: test_add_i64:
+; X64: # BB#0:
+; X64-NEXT: leaq (%rsi,%rdi), %rax
+; X64-NEXT: retq
+;
+; X32-LABEL: test_add_i64:
+; X32: # BB#0:
+; X32-NEXT: pushl %ebp
+; X32-NEXT: .Lcfi0:
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: .Lcfi1:
+; X32-NEXT: .cfi_offset %ebp, -8
+; X32-NEXT: movl %esp, %ebp
+; X32-NEXT: .Lcfi2:
+; X32-NEXT: .cfi_def_cfa_register %ebp
+; X32-NEXT: pushl %esi
+; X32-NEXT: .Lcfi3:
+; X32-NEXT: .cfi_offset %esi, -12
+; X32-NEXT: leal 8(%ebp), %ecx
+; X32-NEXT: leal 12(%ebp), %esi
+; X32-NEXT: leal 16(%ebp), %eax
+; X32-NEXT: movl (%eax), %eax
+; X32-NEXT: leal 20(%ebp), %edx
+; X32-NEXT: movl (%edx), %edx
+; X32-NEXT: addl (%ecx), %eax
+; X32-NEXT: adcl (%esi), %edx
+; X32-NEXT: popl %esi
+; X32-NEXT: popl %ebp
+; X32-NEXT: retl
%ret = add i64 %arg1, %arg2
ret i64 %ret
}
define i32 @test_add_i32(i32 %arg1, i32 %arg2) {
-; ALL-LABEL: test_add_i32:
-; ALL: # BB#0:
-; ALL-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
-; ALL-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def>
-; ALL-NEXT: leal (%rsi,%rdi), %eax
-; ALL-NEXT: retq
+; X64-LABEL: test_add_i32:
+; X64: # BB#0:
+; X64-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def>
+; X64-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def>
+; X64-NEXT: leal (%rsi,%rdi), %eax
+; X64-NEXT: retq
+;
+; X32-LABEL: test_add_i32:
+; X32: # BB#0:
+; X32-NEXT: leal 4(%esp), %ecx
+; X32-NEXT: leal 8(%esp), %eax
+; X32-NEXT: movl (%eax), %eax
+; X32-NEXT: addl (%ecx), %eax
+; X32-NEXT: retl
%ret = add i32 %arg1, %arg2
ret i32 %ret
}
define i16 @test_add_i16(i16 %arg1, i16 %arg2) {
-; ALL-LABEL: test_add_i16:
-; ALL: # BB#0:
-; ALL-NEXT: # kill: %DI<def> %DI<kill> %RDI<def>
-; ALL-NEXT: # kill: %SI<def> %SI<kill> %RSI<def>
-; ALL-NEXT: leal (%rsi,%rdi), %eax
-; ALL-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
-; ALL-NEXT: retq
+; X64-LABEL: test_add_i16:
+; X64: # BB#0:
+; X64-NEXT: # kill: %DI<def> %DI<kill> %RDI<def>
+; X64-NEXT: # kill: %SI<def> %SI<kill> %RSI<def>
+; X64-NEXT: leal (%rsi,%rdi), %eax
+; X64-NEXT: # kill: %AX<def> %AX<kill> %EAX<kill>
+; X64-NEXT: retq
+;
+; X32-LABEL: test_add_i16:
+; X32: # BB#0:
+; X32-NEXT: leal 4(%esp), %ecx
+; X32-NEXT: leal 8(%esp), %eax
+; X32-NEXT: movzwl (%eax), %eax
+; X32-NEXT: addw (%ecx), %ax
+; X32-NEXT: retl
%ret = add i16 %arg1, %arg2
ret i16 %ret
}
define i8 @test_add_i8(i8 %arg1, i8 %arg2) {
-; ALL-LABEL: test_add_i8:
-; ALL: # BB#0:
-; ALL-NEXT: addb %dil, %sil
-; ALL-NEXT: movl %esi, %eax
-; ALL-NEXT: retq
+; X64-LABEL: test_add_i8:
+; X64: # BB#0:
+; X64-NEXT: addb %dil, %sil
+; X64-NEXT: movl %esi, %eax
+; X64-NEXT: retq
+;
+; X32-LABEL: test_add_i8:
+; X32: # BB#0:
+; X32-NEXT: leal 4(%esp), %ecx
+; X32-NEXT: leal 8(%esp), %eax
+; X32-NEXT: movb (%eax), %al
+; X32-NEXT: addb (%ecx), %al
+; X32-NEXT: retl
%ret = add i8 %arg1, %arg2
ret i8 %ret
}
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-add.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-add.mir?rev=303255&r1=303254&r2=303255&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-add.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-add.mir Wed May 17 07:48:08 2017
@@ -1,40 +1,67 @@
-# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
-
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X64
+# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=X32
--- |
- ; ModuleID = '<stdin>'
- source_filename = "<stdin>"
- target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
- target triple = "x86_64--linux-gnu"
+ define void @test_add_i32() {
+ ret void
+ }
- define i32 @test_add_i32(i32 %arg1, i32 %arg2) {
- %ret = add i32 %arg1, %arg2
- ret i32 %ret
+ define void @test_add_i64() {
+ ret void
}
...
---
name: test_add_i32
+# ALL-LABEL: name: test_add_i32
alignment: 4
legalized: false
regBankSelected: false
-selected: false
-tracksRegLiveness: true
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
+# ALL: %0(s32) = IMPLICIT_DEF
+# ALL-NEXT: %1(s32) = IMPLICIT_DEF
+# ALL-NEXT: %2(s32) = G_ADD %0, %1
+# ALL-NEXT: RET 0
body: |
bb.1 (%ir-block.0):
- liveins: %edi, %esi
- ; CHECK-LABEL: name: test_add_i32
- ; CHECK: [[VAL1:%.*]](s32) = COPY %edi
- ; CHECK: [[VAL2:%.*]](s32) = COPY %esi
- ; CHECK: [[RES:%.*]](s32) = G_ADD [[VAL1:%.*]], [[VAL2:%.*]]
-
- %0(s32) = COPY %edi
- %1(s32) = COPY %esi
+ %0(s32) = IMPLICIT_DEF
+ %1(s32) = IMPLICIT_DEF
%2(s32) = G_ADD %0, %1
- %eax = COPY %2(s32)
- RET 0, implicit %eax
+ RET 0
+
+...
+---
+name: test_add_i64
+# ALL-LABEL: name: test_add_i64
+alignment: 4
+legalized: false
+regBankSelected: false
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+# X64: %0(s64) = IMPLICIT_DEF
+# X64-NEXT: %1(s64) = IMPLICIT_DEF
+# X64-NEXT: %2(s64) = G_ADD %0, %1
+# X64-NEXT: RET 0
+#
+# X32: %0(s64) = IMPLICIT_DEF
+# X32-NEXT: %1(s64) = IMPLICIT_DEF
+# X32-NEXT: %3(s32), %4(s32) = G_UNMERGE_VALUES %0(s64)
+# X32-NEXT: %5(s32), %6(s32) = G_UNMERGE_VALUES %1(s64)
+# X32-NEXT: %12(s8) = G_CONSTANT i8 0
+# X32-NEXT: %7(s1) = G_TRUNC %12(s8)
+# X32-NEXT: %8(s32), %9(s1) = G_UADDE %3, %5, %7
+# X32-NEXT: %10(s32), %11(s1) = G_UADDE %4, %6, %9
+# X32-NEXT: %2(s64) = G_MERGE_VALUES %8(s32), %10(s32)
+# X32-NEXT: RET 0
+body: |
+ bb.1 (%ir-block.0):
+ %0(s64) = IMPLICIT_DEF
+ %1(s64) = IMPLICIT_DEF
+ %2(s64) = G_ADD %0, %1
+ RET 0
...
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X32.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X32.mir?rev=303255&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X32.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X32.mir Wed May 17 07:48:08 2017
@@ -0,0 +1,36 @@
+# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
+# RUN: llc -mtriple=i386-linux-gnu -global-isel -regbankselect-greedy -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
+
+--- |
+ define void @test_uadde_i32() {
+ ret void
+ }
+
+...
+---
+name: test_uadde_i32
+# CHECK-LABEL: name: test_uadde_i32
+alignment: 4
+legalized: true
+regBankSelected: false
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: gpr }
+# CHECK-NEXT: - { id: 1, class: gpr }
+# CHECK-NEXT: - { id: 2, class: gpr }
+# CHECK-NEXT: - { id: 3, class: gpr }
+# CHECK-NEXT: - { id: 4, class: gpr }
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+ - { id: 4, class: _ }
+body: |
+ bb.0 (%ir-block.0):
+ %0(s32) = IMPLICIT_DEF
+ %1(s32) = IMPLICIT_DEF
+ %2(s1) = IMPLICIT_DEF
+ %3(s32), %4(s1) = G_UADDE %0, %1, %2
+ RET 0
+
+...
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-add-x32.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-add-x32.mir?rev=303255&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-add-x32.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-add-x32.mir Wed May 17 07:48:08 2017
@@ -0,0 +1,63 @@
+# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=X32
+--- |
+ define i64 @test_add_i64(i64 %a, i64 %b) {
+ %r = add i64 %a, %b
+ ret i64 %r
+ }
+
+...
+---
+name: test_add_i64
+# X32-LABEL: name: test_add_i64
+alignment: 4
+legalized: true
+regBankSelected: true
+# X32: registers:
+# X32-NEXT: - { id: 0, class: gr32 }
+# X32-NEXT: - { id: 1, class: gr32 }
+# X32-NEXT: - { id: 2, class: gr32 }
+# X32-NEXT: - { id: 3, class: gr32 }
+# X32-NEXT: - { id: 4, class: gpr }
+# X32-NEXT: - { id: 5, class: gr32 }
+# X32-NEXT: - { id: 6, class: gr32 }
+# X32-NEXT: - { id: 7, class: gr32 }
+# X32-NEXT: - { id: 8, class: gr32 }
+# X32-NEXT: - { id: 9, class: gpr }
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+ - { id: 3, class: gpr }
+ - { id: 4, class: gpr }
+ - { id: 5, class: gpr }
+ - { id: 6, class: gpr }
+ - { id: 7, class: gpr }
+ - { id: 8, class: gpr }
+ - { id: 9, class: gpr }
+# X32: %0 = IMPLICIT_DEF
+# X32-NEXT: %1 = IMPLICIT_DEF
+# X32-NEXT: %2 = IMPLICIT_DEF
+# X32-NEXT: %3 = IMPLICIT_DEF
+# X32-NEXT: %5 = ADD32rr %0, %2, implicit-def %eflags
+# X32-NEXT: %6 = COPY %eflags
+# X32-NEXT: %eflags = COPY %6
+# X32-NEXT: %7 = ADC32rr %1, %3, implicit-def %eflags, implicit %eflags
+# X32-NEXT: %8 = COPY %eflags
+# X32-NEXT: %eax = COPY %5
+# X32-NEXT: %edx = COPY %7
+# X32-NEXT: RET 0, implicit %eax, implicit %edx
+body: |
+ bb.0 (%ir-block.0):
+ %0(s32) = IMPLICIT_DEF
+ %1(s32) = IMPLICIT_DEF
+ %2(s32) = IMPLICIT_DEF
+ %3(s32) = IMPLICIT_DEF
+ %9(s8) = G_CONSTANT i8 0
+ %4(s1) = G_TRUNC %9(s8)
+ %5(s32), %6(s1) = G_UADDE %0, %2, %4
+ %7(s32), %8(s1) = G_UADDE %1, %3, %6
+ %eax = COPY %5(s32)
+ %edx = COPY %7(s32)
+ RET 0, implicit %eax, implicit %edx
+
+...
More information about the llvm-commits
mailing list