[GlobalISel][X86] G_ICMP support.

Summary: support G_ICMP for scalar types i8/i16/i64.

Reviewers: zvi, guyblank

Reviewed By: guyblank

Subscribers: rovka, kristof.beyls, llvm-commits, krytarowski

Differential Revision: https://reviews.llvm.org/D32995

llvm-svn: 302774
This commit is contained in:
Igor Breger 2017-05-11 07:17:40 +00:00
parent 215f55f526
commit c7b5977bb1
6 changed files with 1090 additions and 5 deletions

View File

@ -73,6 +73,8 @@ private:
MachineFunction &MF) const;
bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
MachineFunction &MF) const;
const X86TargetMachine &TM;
const X86Subtarget &STI;
@ -245,6 +247,8 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
return true;
if (selectZext(I, MRI, MF))
return true;
if (selectCmp(I, MRI, MF))
return true;
return false;
}
@ -612,6 +616,59 @@ bool X86InstructionSelector::selectZext(MachineInstr &I,
return false;
}
bool X86InstructionSelector::selectCmp(MachineInstr &I,
MachineRegisterInfo &MRI,
MachineFunction &MF) const {
if (I.getOpcode() != TargetOpcode::G_ICMP)
return false;
X86::CondCode CC;
bool SwapArgs;
std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
(CmpInst::Predicate)I.getOperand(1).getPredicate());
unsigned OpSet = X86::getSETFromCond(CC);
unsigned LHS = I.getOperand(2).getReg();
unsigned RHS = I.getOperand(3).getReg();
if (SwapArgs)
std::swap(LHS, RHS);
unsigned OpCmp;
LLT Ty = MRI.getType(LHS);
switch (Ty.getSizeInBits()) {
default:
return false;
case 8:
OpCmp = X86::CMP8rr;
break;
case 16:
OpCmp = X86::CMP16rr;
break;
case 32:
OpCmp = X86::CMP32rr;
break;
case 64:
OpCmp = X86::CMP64rr;
break;
}
MachineInstr &CmpInst =
*BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
.addReg(LHS)
.addReg(RHS);
MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(OpSet), I.getOperand(0).getReg());
constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
I.eraseFromParent();
return true;
}
InstructionSelector *
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
X86Subtarget &Subtarget,

View File

@ -91,6 +91,12 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
setAction({G_ZEXT, 1, Ty}, Legal);
setAction({G_SEXT, 1, Ty}, Legal);
}
// Comparison
setAction({G_ICMP, s1}, Legal);
for (auto Ty : {s8, s16, s32, p0})
setAction({G_ICMP, 1, Ty}, Legal);
}
void X86LegalizerInfo::setLegalizerInfo64bit() {
@ -143,6 +149,12 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
setAction({G_ZEXT, 1, Ty}, Legal);
setAction({G_SEXT, 1, Ty}, Legal);
}
// Comparison
setAction({G_ICMP, s1}, Legal);
for (auto Ty : {s8, s16, s32, s64, p0})
setAction({G_ICMP, 1, Ty}, Legal);
}
void X86LegalizerInfo::setLegalizerInfoSSE1() {

View File

@ -0,0 +1,159 @@
; 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
define i32 @test_icmp_eq_i8(i8 %a, i8 %b) {
; ALL-LABEL: test_icmp_eq_i8:
; ALL: # BB#0:
; ALL-NEXT: cmpb %sil, %dil
; ALL-NEXT: sete %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp eq i8 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_eq_i16(i16 %a, i16 %b) {
; ALL-LABEL: test_icmp_eq_i16:
; ALL: # BB#0:
; ALL-NEXT: cmpw %si, %di
; ALL-NEXT: sete %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp eq i16 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_eq_i64(i64 %a, i64 %b) {
; ALL-LABEL: test_icmp_eq_i64:
; ALL: # BB#0:
; ALL-NEXT: cmpq %rsi, %rdi
; ALL-NEXT: sete %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp eq i64 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_eq_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_eq_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: sete %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp eq i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ne_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_ne_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setne %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp ne i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ugt_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_ugt_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: seta %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp ugt i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_uge_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_uge_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setae %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp uge i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ult_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_ult_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setb %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp ult i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ule_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_ule_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setbe %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp ule i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_sgt_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_sgt_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setg %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp sgt i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_sge_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_sge_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setge %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp sge i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_slt_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_slt_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setl %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp slt i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_sle_i32(i32 %a, i32 %b) {
; ALL-LABEL: test_icmp_sle_i32:
; ALL: # BB#0:
; ALL-NEXT: cmpl %esi, %edi
; ALL-NEXT: setle %al
; ALL-NEXT: andl $1, %eax
; ALL-NEXT: retq
%r = icmp sle i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}

View File

@ -0,0 +1,179 @@
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
--- |
define i32 @test_cmp_i8(i8 %a, i8 %b) {
%r = icmp ult i8 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_cmp_i16(i16 %a, i16 %b) {
%r = icmp ult i16 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_cmp_i32(i32 %a, i32 %b) {
%r = icmp ult i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_cmp_i64(i64 %a, i64 %b) {
%r = icmp ult i64 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_cmp_p0(i32* %a, i32* %b) {
%r = icmp ult i32* %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
...
---
name: test_cmp_i8
# CHECK-LABEL: name: test_cmp_i8
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
- { id: 3, class: _ }
# CHECK: %0(s8) = COPY %edi
# CHECK-NEXT: %1(s8) = COPY %esi
# CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s8), %1
# CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
# CHECK-NEXT: %eax = COPY %3(s32)
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s8) = COPY %edi
%1(s8) = COPY %esi
%2(s1) = G_ICMP intpred(ult), %0(s8), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_cmp_i16
# CHECK-LABEL: name: test_cmp_i16
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
- { id: 3, class: _ }
# CHECK: %0(s16) = COPY %edi
# CHECK-NEXT: %1(s16) = COPY %esi
# CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s16), %1
# CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
# CHECK-NEXT: %eax = COPY %3(s32)
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s16) = COPY %edi
%1(s16) = COPY %esi
%2(s1) = G_ICMP intpred(ult), %0(s16), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_cmp_i32
# CHECK-LABEL: name: test_cmp_i32
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
- { id: 3, class: _ }
# CHECK: %0(s32) = COPY %edi
# CHECK-NEXT: %1(s32) = COPY %esi
# CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s32), %1
# CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
# CHECK-NEXT: %eax = COPY %3(s32)
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(ult), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_cmp_i64
# CHECK-LABEL: name: test_cmp_i64
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
- { id: 3, class: _ }
# CHECK: %0(s64) = COPY %rdi
# CHECK-NEXT: %1(s64) = COPY %rsi
# CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s64), %1
# CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
# CHECK-NEXT: %eax = COPY %3(s32)
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %rdi, %rsi
%0(s64) = COPY %rdi
%1(s64) = COPY %rsi
%2(s1) = G_ICMP intpred(ult), %0(s64), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_cmp_p0
# CHECK-LABEL: name: test_cmp_p0
alignment: 4
legalized: false
regBankSelected: false
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
- { id: 3, class: _ }
# CHECK: %0(p0) = COPY %rdi
# CHECK-NEXT: %1(p0) = COPY %rsi
# CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(p0), %1
# CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
# CHECK-NEXT: %eax = COPY %3(s32)
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %rdi, %rsi
%0(p0) = COPY %rdi
%1(p0) = COPY %rsi
%2(s1) = G_ICMP intpred(ult), %0(p0), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...

View File

@ -2,11 +2,6 @@
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -regbankselect-greedy -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
--- |
; ModuleID = 'tmp.ll'
source_filename = "tmp.ll"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64--linux-gnu"
define i8 @test_add_i8(i8 %arg1, i8 %arg2) {
%ret = add i8 %arg1, %arg2
ret i8 %ret
@ -120,6 +115,26 @@
ret void
}
define i1 @test_icmp_eq_i8(i8 %a, i8 %b) {
%r = icmp eq i8 %a, %b
ret i1 %r
}
define i1 @test_icmp_eq_i16(i16 %a, i16 %b) {
%r = icmp eq i16 %a, %b
ret i1 %r
}
define i1 @test_icmp_eq_i32(i32 %a, i32 %b) {
%r = icmp eq i32 %a, %b
ret i1 %r
}
define i1 @test_icmp_eq_i64(i64 %a, i64 %b) {
%r = icmp eq i64 %a, %b
ret i1 %r
}
...
---
name: test_add_i8
@ -735,3 +750,103 @@ body: |
RET 0
...
---
name: test_icmp_eq_i8
# CHECK-LABEL: name: test_icmp_eq_i8
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 }
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s8) = COPY %edi
%1(s8) = COPY %esi
%2(s1) = G_ICMP intpred(eq), %0(s8), %1
%al = COPY %2(s1)
RET 0, implicit %al
...
---
name: test_icmp_eq_i16
# CHECK-LABEL: name: test_icmp_eq_i16
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 }
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s16) = COPY %edi
%1(s16) = COPY %esi
%2(s1) = G_ICMP intpred(eq), %0(s16), %1
%al = COPY %2(s1)
RET 0, implicit %al
...
---
name: test_icmp_eq_i32
# CHECK-LABEL: name: test_icmp_eq_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 }
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(eq), %0(s32), %1
%al = COPY %2(s1)
RET 0, implicit %al
...
---
name: test_icmp_eq_i64
# CHECK-LABEL: name: test_icmp_eq_i64
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 }
registers:
- { id: 0, class: _ }
- { id: 1, class: _ }
- { id: 2, class: _ }
body: |
bb.1 (%ir-block.0):
liveins: %rdi, %rsi
%0(s64) = COPY %rdi
%1(s64) = COPY %rsi
%2(s1) = G_ICMP intpred(eq), %0(s64), %1
%al = COPY %2(s1)
RET 0, implicit %al
...

View File

@ -0,0 +1,563 @@
# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK
--- |
define i32 @test_icmp_eq_i8(i8 %a, i8 %b) {
%r = icmp eq i8 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_eq_i16(i16 %a, i16 %b) {
%r = icmp eq i16 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_eq_i64(i64 %a, i64 %b) {
%r = icmp eq i64 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_eq_i32(i32 %a, i32 %b) {
%r = icmp eq i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ne_i32(i32 %a, i32 %b) {
%r = icmp ne i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ugt_i32(i32 %a, i32 %b) {
%r = icmp ugt i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_uge_i32(i32 %a, i32 %b) {
%r = icmp uge i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ult_i32(i32 %a, i32 %b) {
%r = icmp ult i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_ule_i32(i32 %a, i32 %b) {
%r = icmp ule i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_sgt_i32(i32 %a, i32 %b) {
%r = icmp sgt i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_sge_i32(i32 %a, i32 %b) {
%r = icmp sge i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_slt_i32(i32 %a, i32 %b) {
%r = icmp slt i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
define i32 @test_icmp_sle_i32(i32 %a, i32 %b) {
%r = icmp sle i32 %a, %b
%res = zext i1 %r to i32
ret i32 %res
}
...
---
name: test_icmp_eq_i8
# CHECK-LABEL: name: test_icmp_eq_i8
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr8 }
# CHECK-NEXT: - { id: 1, class: gr8 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %dil
# CHECK-NEXT: %1 = COPY %sil
# CHECK-NEXT: CMP8rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s8) = COPY %edi
%1(s8) = COPY %esi
%2(s1) = G_ICMP intpred(eq), %0(s8), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_eq_i16
# CHECK-LABEL: name: test_icmp_eq_i16
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr16 }
# CHECK-NEXT: - { id: 1, class: gr16 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %di
# CHECK-NEXT: %1 = COPY %si
# CHECK-NEXT: CMP16rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s16) = COPY %edi
%1(s16) = COPY %esi
%2(s1) = G_ICMP intpred(eq), %0(s16), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_eq_i64
# CHECK-LABEL: name: test_icmp_eq_i64
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr64 }
# CHECK-NEXT: - { id: 1, class: gr64 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %rdi
# CHECK-NEXT: %1 = COPY %rsi
# CHECK-NEXT: CMP64rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %rdi, %rsi
%0(s64) = COPY %rdi
%1(s64) = COPY %rsi
%2(s1) = G_ICMP intpred(eq), %0(s64), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_eq_i32
# CHECK-LABEL: name: test_icmp_eq_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(eq), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_ne_i32
# CHECK-LABEL: name: test_icmp_ne_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETNEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(ne), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_ugt_i32
# CHECK-LABEL: name: test_icmp_ugt_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETAr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(ugt), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_uge_i32
# CHECK-LABEL: name: test_icmp_uge_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETAEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(uge), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_ult_i32
# CHECK-LABEL: name: test_icmp_ult_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETBr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(ult), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_ule_i32
# CHECK-LABEL: name: test_icmp_ule_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETBEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(ule), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_sgt_i32
# CHECK-LABEL: name: test_icmp_sgt_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETGr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(sgt), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_sge_i32
# CHECK-LABEL: name: test_icmp_sge_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETGEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(sge), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_slt_i32
# CHECK-LABEL: name: test_icmp_slt_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETLr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(slt), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...
---
name: test_icmp_sle_i32
# CHECK-LABEL: name: test_icmp_sle_i32
alignment: 4
legalized: true
regBankSelected: true
# CHECK: registers:
# CHECK-NEXT: - { id: 0, class: gr32 }
# CHECK-NEXT: - { id: 1, class: gr32 }
# CHECK-NEXT: - { id: 2, class: gr8 }
# CHECK-NEXT: - { id: 3, class: gr32 }
# CHECK-NEXT: - { id: 4, class: gr32 }
registers:
- { id: 0, class: gpr }
- { id: 1, class: gpr }
- { id: 2, class: gpr }
- { id: 3, class: gpr }
# CHECK: %0 = COPY %edi
# CHECK-NEXT: %1 = COPY %esi
# CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
# CHECK-NEXT: %2 = SETLEr implicit %eflags
# CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
# CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
# CHECK-NEXT: %eax = COPY %3
# CHECK-NEXT: RET 0, implicit %eax
body: |
bb.1 (%ir-block.0):
liveins: %edi, %esi
%0(s32) = COPY %edi
%1(s32) = COPY %esi
%2(s1) = G_ICMP intpred(sle), %0(s32), %1
%3(s32) = G_ZEXT %2(s1)
%eax = COPY %3(s32)
RET 0, implicit %eax
...