[llvm] r302774 - [GlobalISel][X86] G_ICMP support.
Igor Breger via llvm-commits
llvm-commits at lists.llvm.org
Thu May 11 00:17:41 PDT 2017
Author: ibreger
Date: Thu May 11 02:17:40 2017
New Revision: 302774
URL: http://llvm.org/viewvc/llvm-project?rev=302774&view=rev
Log:
[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
Added:
llvm/trunk/test/CodeGen/X86/GlobalISel/cmp.ll
llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-cmp.mir
llvm/trunk/test/CodeGen/X86/GlobalISel/select-cmp.mir
Modified:
llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
Modified: llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp?rev=302774&r1=302773&r2=302774&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstructionSelector.cpp Thu May 11 02:17:40 2017
@@ -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(Mach
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(
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,
Modified: llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp?rev=302774&r1=302773&r2=302774&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86LegalizerInfo.cpp Thu May 11 02:17:40 2017
@@ -91,6 +91,12 @@ void X86LegalizerInfo::setLegalizerInfo3
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::setLegalizerInfo6
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() {
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/cmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/cmp.ll?rev=302774&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/cmp.ll (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/cmp.ll Thu May 11 02:17:40 2017
@@ -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
+}
+
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-cmp.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-cmp.mir?rev=302774&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-cmp.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/legalize-cmp.mir Thu May 11 02:17:40 2017
@@ -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
+
+...
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir?rev=302774&r1=302773&r2=302774&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir Thu May 11 02:17:40 2017
@@ -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
+
+...
Added: llvm/trunk/test/CodeGen/X86/GlobalISel/select-cmp.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/select-cmp.mir?rev=302774&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/select-cmp.mir (added)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/select-cmp.mir Thu May 11 02:17:40 2017
@@ -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
+
+...
More information about the llvm-commits
mailing list