[llvm] r311327 - [GlobalISel][X86] Support G_BRCOND operation.
Igor Breger via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 21 03:51:54 PDT 2017
Author: ibreger
Date: Mon Aug 21 03:51:54 2017
New Revision: 311327
URL: http://llvm.org/viewvc/llvm-project?rev=311327&view=rev
Log:
[GlobalISel][X86] Support G_BRCOND operation.
Summary: Support G_BRCOND operation. For now don't try to fold cmp/trunc instructions.
Reviewers: zvi, guyblank
Reviewed By: guyblank
Subscribers: rovka, llvm-commits, kristof.beyls
Differential Revision: https://reviews.llvm.org/D34754
Added:
llvm/trunk/test/CodeGen/X86/GlobalISel/brcond.ll
llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-brcond.mir
llvm/trunk/test/CodeGen/X86/GlobalISel/select-brcond.mir
Modified:
llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=311327&r1=311326&r2=311327&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Mon Aug 21 03:51:54 2017
@@ -83,6 +83,8 @@ private:
MachineFunction &MF) const;
bool selectExtract(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
+ bool selectCondBranch(MachineInstr &I, MachineRegisterInfo &MRI,
+ MachineFunction &MF) const;
// emit insert subreg instruction and insert it before MachineInstr &I
bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
@@ -330,6 +332,8 @@ bool X86InstructionSelector::select(Mach
return true;
if (selectInsert(I, MRI, MF))
return true;
+ if (selectCondBranch(I, MRI, MF))
+ return true;
return false;
}
@@ -1101,6 +1105,29 @@ bool X86InstructionSelector::selectMerge
I.eraseFromParent();
return true;
}
+
+bool X86InstructionSelector::selectCondBranch(MachineInstr &I,
+ MachineRegisterInfo &MRI,
+ MachineFunction &MF) const {
+ if (I.getOpcode() != TargetOpcode::G_BRCOND)
+ return false;
+
+ const unsigned CondReg = I.getOperand(0).getReg();
+ MachineBasicBlock *DestMBB = I.getOperand(1).getMBB();
+
+ MachineInstr &TestInst =
+ *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST8ri))
+ .addReg(CondReg)
+ .addImm(1);
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::JNE_1))
+ .addMBB(DestMBB);
+
+ constrainSelectedInstRegOperands(TestInst, TII, TRI, RBI);
+
+ I.eraseFromParent();
+ return true;
+}
+
InstructionSelector *
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
X86Subtarget &Subtarget,
Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=311327&r1=311326&r2=311327&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Mon Aug 21 03:51:54 2017
@@ -80,6 +80,9 @@ void X86LegalizerInfo::setLegalizerInfo3
for (auto Ty : {s1, s8, s16})
setAction({G_GEP, 1, Ty}, WidenScalar);
+ // Control-flow
+ setAction({G_BRCOND, s1}, Legal);
+
// Constants
for (auto Ty : {s8, s16, s32, p0})
setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
@@ -141,6 +144,9 @@ void X86LegalizerInfo::setLegalizerInfo6
for (auto Ty : {s1, s8, s16})
setAction({G_GEP, 1, Ty}, WidenScalar);
+ // Control-flow
+ setAction({G_BRCOND, s1}, Legal);
+
// Constants
for (auto Ty : {s8, s16, s32, s64, p0})
setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/brcond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/brcond.ll?rev=311327&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/brcond.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/brcond.ll Mon Aug 21 03:51:54 2017
@@ -0,0 +1,91 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X64
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32
+
+define i32 @test_1(i32 %a, i32 %b, i32 %tValue, i32 %fValue) {
+; X64-LABEL: test_1:
+; X64: # BB#0: # %entry
+; X64-NEXT: cmpl %esi, %edi
+; X64-NEXT: setl %al
+; X64-NEXT: testb $1, %al
+; X64-NEXT: je .LBB0_2
+; X64-NEXT: # BB#1: # %if.then
+; X64-NEXT: movl %edx, -{{[0-9]+}}(%rsp)
+; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax
+; X64-NEXT: retq
+; X64-NEXT: .LBB0_2: # %if.else
+; X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
+; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax
+; X64-NEXT: retq
+;
+; X32-LABEL: test_1:
+; X32: # BB#0: # %entry
+; X32-NEXT: pushl %eax
+; X32-NEXT: .Lcfi0:
+; X32-NEXT: .cfi_def_cfa_offset 8
+; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT: cmpl %eax, {{[0-9]+}}(%esp)
+; X32-NEXT: setl %al
+; X32-NEXT: testb $1, %al
+; X32-NEXT: je .LBB0_2
+; X32-NEXT: # BB#1: # %if.then
+; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT: jmp .LBB0_3
+; X32-NEXT: .LBB0_2: # %if.else
+; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT: .LBB0_3: # %return
+; X32-NEXT: movl %eax, (%esp)
+; X32-NEXT: movl (%esp), %eax
+; X32-NEXT: popl %ecx
+; X32-NEXT: retl
+entry:
+ %retval = alloca i32, align 4
+ %cmp = icmp slt i32 %a, %b
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then:
+ store i32 %tValue, i32* %retval, align 4
+ br label %return
+
+if.else:
+ store i32 %fValue, i32* %retval, align 4
+ br label %return
+
+return:
+ %0 = load i32, i32* %retval, align 4
+ ret i32 %0
+}
+
+define i32 @test_2(i32 %a) {
+; X64-LABEL: test_2:
+; X64: # BB#0: # %entry
+; X64-NEXT: testb $1, %dil
+; X64-NEXT: je .LBB1_2
+; X64-NEXT: # BB#1: # %if.then
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: retq
+; X64-NEXT: .LBB1_2: # %if.else
+; X64-NEXT: movl $1, %eax
+; X64-NEXT: retq
+;
+; X32-LABEL: test_2:
+; X32: # BB#0: # %entry
+; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT: testb $1, %al
+; X32-NEXT: je .LBB1_2
+; X32-NEXT: # BB#1: # %if.then
+; X32-NEXT: xorl %eax, %eax
+; X32-NEXT: retl
+; X32-NEXT: .LBB1_2: # %if.else
+; X32-NEXT: movl $1, %eax
+; X32-NEXT: retl
+entry:
+ %cmp = trunc i32 %a to i1
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then:
+ ret i32 0
+if.else:
+ ret i32 1
+}
+
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-brcond.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-brcond.mir?rev=311327&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-brcond.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-brcond.mir Mon Aug 21 03:51:54 2017
@@ -0,0 +1,58 @@
+# 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
+
+--- |
+
+ define i32 @test(i32 %a) {
+ entry:
+ %cmp = trunc i32 %a to i1
+ br i1 %cmp, label %if.then, label %if.else
+
+ if.then: ; preds = %entry
+ ret i32 0
+
+ if.else: ; preds = %entry
+ ret i32 1
+ }
+...
+---
+name: test
+# ALL-LABEL: name: test
+alignment: 4
+legalized: false
+regBankSelected: false
+registers:
+ - { id: 0, class: _, preferred-register: '' }
+ - { id: 1, class: _, preferred-register: '' }
+ - { id: 2, class: _, preferred-register: '' }
+ - { id: 3, class: _, preferred-register: '' }
+# ALL: %1(s1) = G_TRUNC %0(s32)
+# ALL-NEXT: G_BRCOND %1(s1), %[[TRUE:bb.[0-9]+.if.then]]
+# ALL-NEXT: G_BR %[[FALSE:bb.[0-9]+.if.else]]
+# ALL: [[TRUE]]:
+# ALL-NEXT: %eax = COPY %2(s32)
+# ALL-NEXT: RET 0, implicit %eax
+# ALL: [[FALSE]]:
+# ALL-NEXT: %eax = COPY %3(s32)
+# ALL-NEXT: RET 0, implicit %eax
+body: |
+ bb.1.entry:
+ successors: %bb.2.if.then(0x40000000), %bb.3.if.else(0x40000000)
+ liveins: %edi
+
+ %0(s32) = COPY %edi
+ %2(s32) = G_CONSTANT i32 0
+ %3(s32) = G_CONSTANT i32 1
+ %1(s1) = G_TRUNC %0(s32)
+ G_BRCOND %1(s1), %bb.2.if.then
+ G_BR %bb.3.if.else
+
+ bb.2.if.then:
+ %eax = COPY %2(s32)
+ RET 0, implicit %eax
+
+ bb.3.if.else:
+ %eax = COPY %3(s32)
+ RET 0, implicit %eax
+
+...
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-brcond.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-brcond.mir?rev=311327&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-brcond.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-brcond.mir Mon Aug 21 03:51:54 2017
@@ -0,0 +1,76 @@
+# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X64
+# RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32
+
+--- |
+
+ define i32 @test(i32 %a) {
+ entry:
+ %cmp = trunc i32 %a to i1
+ br i1 %cmp, label %true, label %false
+
+ true: ; preds = %entry
+ ret i32 0
+
+ false: ; preds = %entry
+ ret i32 1
+ }
+
+...
+---
+name: test
+# CHECK-LABEL: name: test
+alignment: 4
+legalized: true
+regBankSelected: true
+# X64: registers:
+# X64-NEXT: - { id: 0, class: gr32, preferred-register: '' }
+# X64-NEXT: - { id: 1, class: gr8, preferred-register: '' }
+# X64-NEXT: - { id: 2, class: gr32, preferred-register: '' }
+# X64-NEXT: - { id: 3, class: gr32, preferred-register: '' }
+#
+# X32: registers:
+# X32-NEXT: - { id: 0, class: gr32_abcd, preferred-register: '' }
+# X32-NEXT: - { id: 1, class: gr8, preferred-register: '' }
+# X32-NEXT: - { id: 2, class: gr32, preferred-register: '' }
+# X32-NEXT: - { id: 3, class: gr32, preferred-register: '' }
+registers:
+ - { id: 0, class: gpr, preferred-register: '' }
+ - { id: 1, class: gpr, preferred-register: '' }
+ - { id: 2, class: gpr, preferred-register: '' }
+ - { id: 3, class: gpr, preferred-register: '' }
+# CHECK: %0 = COPY %edi
+# CHECK-NEXT: %2 = MOV32r0 implicit-def %eflags
+# CHECK-NEXT: %3 = MOV32ri 1
+# CHECK-NEXT: %1 = COPY %0.sub_8bit
+# CHECK-NEXT: TEST8ri %1, 1, implicit-def %eflags
+# CHECK-NEXT: JNE_1 %[[TRUE:bb.[0-9].true]], implicit %eflags
+# CHECK-NEXT: JMP_1 %[[FALSE:bb.[0-9].false]]
+# CHECK: [[TRUE]]:
+# CHECK-NEXT: %eax = COPY %2
+# CHECK-NEXT: RET 0, implicit %eax
+# CHECK: [[FALSE]]:
+# CHECK-NEXT: %eax = COPY %3
+# CHECK-NEXT: RET 0, implicit %eax
+
+
+body: |
+ bb.1.entry:
+ successors: %bb.2.true(0x40000000), %bb.3.false(0x40000000)
+ liveins: %edi
+
+ %0(s32) = COPY %edi
+ %2(s32) = G_CONSTANT i32 0
+ %3(s32) = G_CONSTANT i32 1
+ %1(s1) = G_TRUNC %0(s32)
+ G_BRCOND %1(s1), %bb.2.true
+ G_BR %bb.3.false
+
+ bb.2.true:
+ %eax = COPY %2(s32)
+ RET 0, implicit %eax
+
+ bb.3.false:
+ %eax = COPY %3(s32)
+ RET 0, implicit %eax
+
+...
More information about the llvm-commits
mailing list