From 097556d6bd2f5a724f5ae00207f4d0ed6b224da1 Mon Sep 17 00:00:00 2001 From: Reed Kotler Date: Thu, 25 Oct 2012 21:33:30 +0000 Subject: [PATCH] implement mips16 patterns for select nodes llvm-svn: 166721 --- llvm/lib/Target/Mips/Mips16InstrInfo.td | 381 +++++++++++++++++++++++++++++++- llvm/test/CodeGen/Mips/selpat.ll | 350 +++++++++++++++++++++++++++++ 2 files changed, 729 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/selpat.ll diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.td b/llvm/lib/Target/Mips/Mips16InstrInfo.td index 043b974..c4949ce 100644 --- a/llvm/lib/Target/Mips/Mips16InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips16InstrInfo.td @@ -229,6 +229,95 @@ class FRRR16_ins _f, string asmstr, InstrItinClass itin> : !strconcat(asmstr, "\t$rz, $rx, $ry"), [], itin>; // +// These Sel patterns support the generation of conditional move +// pseudo instructions. +// +// The nomenclature uses the components making up the pseudo and may +// be a bit counter intuitive when compared with the end result we seek. +// For example using a bqez in the example directly below results in the +// conditional move being done if the tested register is not zero. +// I considered in easier to check by keeping the pseudo consistent with +// it's components but it could have been done differently. +// +// The simplest case is when can test and operand directly and do the +// conditional move based on a simple mips16 conditional +// branch instruction. +// for example: +// if $op == beqz or bnez: +// +// $op1 $rt, .+4 +// move $rd, $rs +// +// if $op == beqz, then if $rt != 0, then the conditional assignment +// $rd = $rs is done. + +// if $op == bnez, then if $rt == 0, then the conditional assignment +// $rd = $rs is done. +// +// So this pseudo class only has one operand, i.e. op +// +class Sel f1, string op, InstrItinClass itin>: + MipsInst16_32<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs, + CPU16Regs:$rt), + !strconcat(op, "\t$rt, .+4\n\t\n\tmove $rd, $rs"), [], itin, + Pseudo16> { + let isCodeGenOnly=1; + let Constraints = "$rd = $rd_"; +} + +// +// The next two instruction classes allow for an operand which tests +// two operands and returns a value in register T8 and +//then does a conditional branch based on the value of T8 +// + +// op2 can be cmpi or slti/sltiu +// op1 can bteqz or btnez +// the operands for op2 are a register and a signed constant +// +// $op2 $t, $imm ;test register t and branch conditionally +// $op1 .+4 ;op1 is a conditional branch +// move $rd, $rs +// +// +class SeliT f1, string op1, bits<5> f2, string op2, + InstrItinClass itin>: + MipsInst16_32<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs, + CPU16Regs:$rl, simm16:$imm), + !strconcat(op2, + !strconcat("\t$rl, $imm\n\t", + !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), [], itin, + Pseudo16> { + let isCodeGenOnly=1; + let Constraints = "$rd = $rd_"; +} + +// +// op2 can be cmp or slt/sltu +// op1 can be bteqz or btnez +// the operands for op2 are two registers +// op1 is a conditional branch +// +// +// $op2 $rl, $rr ;test registers rl,rr +// $op1 .+4 ;op2 is a conditional branch +// move $rd, $rs +// +// +class SelT f1, string op1, bits<5> f2, string op2, + InstrItinClass itin>: + MipsInst16_32<(outs CPU16Regs:$rd_), (ins CPU16Regs:$rd, CPU16Regs:$rs, + CPU16Regs:$rl, CPU16Regs:$rr), + !strconcat(op2, + !strconcat("\t$rl, $rr\n\t", + !strconcat(op1, "\t.+4\n\tmove $rd, $rs"))), [], itin, + Pseudo16> { + let isCodeGenOnly=1; + let Constraints = "$rd = $rd_"; +} + + +// // Some general instruction class info // // @@ -565,6 +654,120 @@ def SbRxRyOffMemX16: FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, IIStore>, MayStore; // +// The Sel(T) instructions are pseudos +// T means that they use T8 implicitly. +// +// +// Format: SelBeqZ rd, rs, rt +// Purpose: if rt==0, do nothing +// else rs = rt +// +def SelBeqZ: Sel<0b00100, "beqz", IIAlu>; + +// +// Format: SelTBteqZCmp rd, rs, rl, rr +// Purpose: b = Cmp rl, rr. +// If b==0 then do nothing. +// if b!=0 then rd = rs +// +def SelTBteqZCmp: SelT<0b000, "bteqz", 0b01010, "cmp", IIAlu>; + +// +// Format: SelTBteqZCmpi rd, rs, rl, rr +// Purpose: b = Cmpi rl, imm. +// If b==0 then do nothing. +// if b!=0 then rd = rs +// +def SelTBteqZCmpi: SeliT<0b000, "bteqz", 0b01110, "cmpi", IIAlu>; + +// +// Format: SelTBteqZSlt rd, rs, rl, rr +// Purpose: b = Slt rl, rr. +// If b==0 then do nothing. +// if b!=0 then rd = rs +// +def SelTBteqZSlt: SelT<0b000, "bteqz", 0b00010, "slt", IIAlu>; + +// +// Format: SelTBteqZSlti rd, rs, rl, rr +// Purpose: b = Slti rl, imm. +// If b==0 then do nothing. +// if b!=0 then rd = rs +// +def SelTBteqZSlti: SeliT<0b000, "bteqz", 0b01010, "slti", IIAlu>; + +// +// Format: SelTBteqZSltu rd, rs, rl, rr +// Purpose: b = Sltu rl, rr. +// If b==0 then do nothing. +// if b!=0 then rd = rs +// +def SelTBteqZSltu: SelT<0b000, "bteqz", 0b00011, "sltu", IIAlu>; + +// +// Format: SelTBteqZSltiu rd, rs, rl, rr +// Purpose: b = Sltiu rl, imm. +// If b==0 then do nothing. +// if b!=0 then rd = rs +// +def SelTBteqZSltiu: SeliT<0b000, "bteqz", 0b01011, "sltiu", IIAlu>; + +// +// Format: SelBnez rd, rs, rt +// Purpose: if rt!=0, do nothing +// else rs = rt +// +def SelBneZ: Sel<0b00101, "bnez", IIAlu>; + +// +// Format: SelTBtneZCmp rd, rs, rl, rr +// Purpose: b = Cmp rl, rr. +// If b!=0 then do nothing. +// if b0=0 then rd = rs +// +def SelTBtneZCmp: SelT<0b001, "btnez", 0b01010, "cmp", IIAlu>; + +// +// Format: SelTBtnezCmpi rd, rs, rl, rr +// Purpose: b = Cmpi rl, imm. +// If b!=0 then do nothing. +// if b==0 then rd = rs +// +def SelTBtneZCmpi: SeliT<0b000, "btnez", 0b01110, "cmpi", IIAlu>; + +// +// Format: SelTBtneZSlt rd, rs, rl, rr +// Purpose: b = Slt rl, rr. +// If b!=0 then do nothing. +// if b==0 then rd = rs +// +def SelTBtneZSlt: SelT<0b001, "btnez", 0b00010, "slt", IIAlu>; + +// +// Format: SelTBtneZSlti rd, rs, rl, rr +// Purpose: b = Slti rl, imm. +// If b!=0 then do nothing. +// if b==0 then rd = rs +// +def SelTBtneZSlti: SeliT<0b001, "btnez", 0b01010, "slti", IIAlu>; + +// +// Format: SelTBtneZSltu rd, rs, rl, rr +// Purpose: b = Sltu rl, rr. +// If b!=0 then do nothing. +// if b==0 then rd = rs +// +def SelTBtneZSltu: SelT<0b001, "btnez", 0b00011, "sltu", IIAlu>; + +// +// Format: SelTBtneZSltiu rd, rs, rl, rr +// Purpose: b = Slti rl, imm. +// If b!=0 then do nothing. +// if b==0 then rd = rs +// +def SelTBtneZSltiu: SeliT<0b001, "btnez", 0b01011, "sltiu", IIAlu>; +// +// // Format: SH ry, offset(rx) MIPS16e // Purpose: Store Halfword (Extended) // To store a halfword to memory. @@ -766,7 +969,7 @@ class SetCC_R16: class SetCC_I16: Mips16Pat<(cond_op CPU16Regs:$rx, imm_type:$imm16), - (I CPU16Regs:$rx, imm_type:$imm16)>; + (I CPU16Regs:$rx, imm_type:$imm16)>; // @@ -922,6 +1125,180 @@ def: Mips16Pat <(MipsDivRemU CPU16Regs:$rx, CPU16Regs:$ry), (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>; +// signed a,b +// x = (a>=b)?x:y +// +// if !(a < b) x = y +// +def : Mips16Pat<(select (i32 (setge CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a, CPU16Regs:$b)>; + +// signed a,b +// x = (a>b)?x:y +// +// if (b < a) x = y +// +def : Mips16Pat<(select (i32 (setgt CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBtneZSlt CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$b, CPU16Regs:$a)>; + +// unsigned a,b +// x = (a>=b)?x:y +// +// if !(a < b) x = y; +// +def : Mips16Pat< + (select (i32 (setuge CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a, CPU16Regs:$b)>; + +// unsigned a,b +// x = (a>b)?x:y +// +// if (b < a) x = y +// +def : Mips16Pat<(select (i32 (setugt CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBtneZSltu CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$b, CPU16Regs:$a)>; + +// signed +// x = (a >= k)?x:y +// due to an llvm optimization, i don't think that this will ever +// be used. This is transformed into x = (a > k-1)?x:y +// +// + +//def : Mips16Pat< +// (select (i32 (setge CPU16Regs:$lhs, immSExt16:$rhs)), +// CPU16Regs:$T, CPU16Regs:$F), +// (SelTBteqZSlti CPU16Regs:$T, CPU16Regs:$F, +// CPU16Regs:$lhs, immSExt16:$rhs)>; + +//def : Mips16Pat< +// (select (i32 (setuge CPU16Regs:$lhs, immSExt16:$rhs)), +// CPU16Regs:$T, CPU16Regs:$F), +// (SelTBteqZSltiu CPU16Regs:$T, CPU16Regs:$F, +// CPU16Regs:$lhs, immSExt16:$rhs)>; + +// signed +// x = (a < k)?x:y +// +// if !(a < k) x = y; +// +def : Mips16Pat< + (select (i32 (setlt CPU16Regs:$a, immSExt16:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBtneZSlti CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a, immSExt16:$b)>; + + +// +// +// signed +// x = (a <= b)? x : y +// +// if (b < a) x = y +// +def : Mips16Pat<(select (i32 (setle CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBteqZSlt CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$b, CPU16Regs:$a)>; + +// +// unnsigned +// x = (a <= b)? x : y +// +// if (b < a) x = y +// +def : Mips16Pat<(select (i32 (setule CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBteqZSltu CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$b, CPU16Regs:$a)>; + +// +// signed/unsigned +// x = (a == b)? x : y +// +// if (a != b) x = y +// +def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBteqZCmp CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$b, CPU16Regs:$a)>; + +// +// signed/unsigned +// x = (a == 0)? x : y +// +// if (a != 0) x = y +// +def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, 0)), + CPU16Regs:$x, CPU16Regs:$y), + (SelBeqZ CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a)>; + + +// +// signed/unsigned +// x = (a == k)? x : y +// +// if (a != k) x = y +// +def : Mips16Pat<(select (i32 (seteq CPU16Regs:$a, immZExt16:$k)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBteqZCmpi CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a, immZExt16:$k)>; + + +// +// signed/unsigned +// x = (a != b)? x : y +// +// if (a == b) x = y +// +// +def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, CPU16Regs:$b)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBtneZCmp CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$b, CPU16Regs:$a)>; + +// +// signed/unsigned +// x = (a != 0)? x : y +// +// if (a == 0) x = y +// +def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, 0)), + CPU16Regs:$x, CPU16Regs:$y), + (SelBneZ CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a)>; + +// signed/unsigned +// x = (a)? x : y +// +// if (!a) x = y +// +def : Mips16Pat<(select CPU16Regs:$a, + CPU16Regs:$x, CPU16Regs:$y), + (SelBneZ CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a)>; + + +// +// signed/unsigned +// x = (a != k)? x : y +// +// if (a == k) x = y +// +def : Mips16Pat<(select (i32 (setne CPU16Regs:$a, immZExt16:$k)), + CPU16Regs:$x, CPU16Regs:$y), + (SelTBtneZCmpi CPU16Regs:$x, CPU16Regs:$y, + CPU16Regs:$a, immZExt16:$k)>; // // When writing C code to test setxx these patterns, @@ -1013,7 +1390,7 @@ def: Mips16Pat //def: Mips16Pat // <(setuge CPU16Regs:$lhs, immZExt16:$rhs), // (XorRxRxRy16 (SltiuCCRxImmX16 CPU16Regs:$lhs, immZExt16:$rhs), -// (LiRxImmX16 1))>; +// (LiRxImmX16 1))>; // // setugt diff --git a/llvm/test/CodeGen/Mips/selpat.ll b/llvm/test/CodeGen/Mips/selpat.ll new file mode 100644 index 0000000..cda0c96 --- /dev/null +++ b/llvm/test/CodeGen/Mips/selpat.ll @@ -0,0 +1,350 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@t = global i32 10, align 4 +@f = global i32 199, align 4 +@a = global i32 1, align 4 +@b = global i32 10, align 4 +@c = global i32 1, align 4 +@z1 = common global i32 0, align 4 +@z2 = common global i32 0, align 4 +@z3 = common global i32 0, align 4 +@z4 = common global i32 0, align 4 + +define void @calc_seleq() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp eq i32 %0, %1 + %2 = load i32* @f, align 4 + %3 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + store i32 %cond, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp eq i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %3, i32 %2 + store i32 %cond10, i32* @z3, align 4 + store i32 %cond10, i32* @z4, align 4 + ret void +} + + +define void @calc_seleqk() nounwind { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp eq i32 %0, 1 + %1 = load i32* @t, align 4 + %2 = load i32* @f, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @z1, align 4 +; 16: cmpi ${{[0-9]+}}, 1 +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp eq i32 %0, 10 + %cond5 = select i1 %cmp1, i32 %2, i32 %1 + store i32 %cond5, i32* @z2, align 4 + %3 = load i32* @b, align 4 + %cmp6 = icmp eq i32 %3, 3 + %cond10 = select i1 %cmp6, i32 %2, i32 %1 + store i32 %cond10, i32* @z3, align 4 +; 16: cmpi ${{[0-9]+}}, 10 +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp11 = icmp eq i32 %3, 10 + %cond15 = select i1 %cmp11, i32 %1, i32 %2 + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define void @calc_seleqz() nounwind { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp eq i32 %0, 0 + %1 = load i32* @t, align 4 + %2 = load i32* @f, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @z1, align 4 +; 16: beqz ${{[0-9]+}}, .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %3 = load i32* @b, align 4 + %cmp1 = icmp eq i32 %3, 0 + %cond5 = select i1 %cmp1, i32 %2, i32 %1 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp eq i32 %4, 0 + %cond10 = select i1 %cmp6, i32 %1, i32 %2 + store i32 %cond10, i32* @z3, align 4 + store i32 %cond, i32* @z4, align 4 + ret void +} + +define void @calc_selge() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp sge i32 %0, %1 + %2 = load i32* @f, align 4 + %3 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp sge i32 %1, %0 + %cond5 = select i1 %cmp1, i32 %3, i32 %2 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp sge i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %3, i32 %2 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp sge i32 %0, %4 + %cond15 = select i1 %cmp11, i32 %3, i32 %2 + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define i32 @calc_selgt() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp sgt i32 %0, %1 +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %2 = load i32* @f, align 4 + %3 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 + %cmp1 = icmp sgt i32 %1, %0 + %cond5 = select i1 %cmp1, i32 %3, i32 %2 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp sgt i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %2, i32 %3 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp sgt i32 %0, %4 + %cond15 = select i1 %cmp11, i32 %2, i32 %3 + store i32 %cond15, i32* @z4, align 4 + ret i32 undef +} + +define void @calc_selle() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp sle i32 %0, %1 + %2 = load i32* @t, align 4 + %3 = load i32* @f, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: slt ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp sle i32 %1, %0 + %cond5 = select i1 %cmp1, i32 %3, i32 %2 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp sle i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %2, i32 %3 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp sle i32 %0, %4 + %cond15 = select i1 %cmp11, i32 %2, i32 %3 + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define void @calc_selltk() nounwind { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp slt i32 %0, 10 + %1 = load i32* @t, align 4 + %2 = load i32* @f, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @z1, align 4 +; 16: slti ${{[0-9]+}}, {{[0-9]+}} +; 16: btnez .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %3 = load i32* @b, align 4 + %cmp1 = icmp slt i32 %3, 2 + %cond5 = select i1 %cmp1, i32 %2, i32 %1 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp sgt i32 %4, 2 + %cond10 = select i1 %cmp6, i32 %2, i32 %1 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp sgt i32 %0, 2 + %cond15 = select i1 %cmp11, i32 %2, i32 %1 + store i32 %cond15, i32* @z4, align 4 + ret void +} + + +define void @calc_selne() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp ne i32 %0, %1 + %2 = load i32* @t, align 4 + %3 = load i32* @f, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: cmp ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + store i32 %cond, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp ne i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %3, i32 %2 + store i32 %cond10, i32* @z3, align 4 + store i32 %cond10, i32* @z4, align 4 + ret void +} + +define void @calc_selnek() nounwind { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp ne i32 %0, 1 + %1 = load i32* @f, align 4 + %2 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @z1, align 4 +; 16: cmpi ${{[0-9]+}}, 1 +; 16: btnez .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp ne i32 %0, 10 + %cond5 = select i1 %cmp1, i32 %2, i32 %1 + store i32 %cond5, i32* @z2, align 4 + %3 = load i32* @b, align 4 + %cmp6 = icmp ne i32 %3, 3 + %cond10 = select i1 %cmp6, i32 %2, i32 %1 + store i32 %cond10, i32* @z3, align 4 +; 16: cmpi ${{[0-9]+}}, 10 +; 16: btnez .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp11 = icmp ne i32 %3, 10 + %cond15 = select i1 %cmp11, i32 %1, i32 %2 + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define void @calc_selnez() nounwind { +entry: + %0 = load i32* @a, align 4 + %cmp = icmp ne i32 %0, 0 + %1 = load i32* @f, align 4 + %2 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %1, i32 %2 + store i32 %cond, i32* @z1, align 4 +; 16: bnez ${{[0-9]+}}, .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %3 = load i32* @b, align 4 + %cmp1 = icmp ne i32 %3, 0 + %cond5 = select i1 %cmp1, i32 %2, i32 %1 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp ne i32 %4, 0 + %cond10 = select i1 %cmp6, i32 %1, i32 %2 + store i32 %cond10, i32* @z3, align 4 + store i32 %cond, i32* @z4, align 4 + ret void +} + +define void @calc_selnez2() nounwind { +entry: + %0 = load i32* @a, align 4 + %tobool = icmp ne i32 %0, 0 + %1 = load i32* @f, align 4 + %2 = load i32* @t, align 4 + %cond = select i1 %tobool, i32 %1, i32 %2 + store i32 %cond, i32* @z1, align 4 +; 16: bnez ${{[0-9]+}}, .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %3 = load i32* @b, align 4 + %tobool1 = icmp ne i32 %3, 0 + %cond5 = select i1 %tobool1, i32 %2, i32 %1 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %tobool6 = icmp ne i32 %4, 0 + %cond10 = select i1 %tobool6, i32 %1, i32 %2 + store i32 %cond10, i32* @z3, align 4 + store i32 %cond, i32* @z4, align 4 + ret void +} + +define void @calc_seluge() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp uge i32 %0, %1 + %2 = load i32* @f, align 4 + %3 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp uge i32 %1, %0 + %cond5 = select i1 %cmp1, i32 %3, i32 %2 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp uge i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %3, i32 %2 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp uge i32 %0, %4 + %cond15 = select i1 %cmp11, i32 %3, i32 %2 + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define void @calc_selugt() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp ugt i32 %0, %1 + %2 = load i32* @f, align 4 + %3 = load i32* @t, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} +; 16: btnez .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp ugt i32 %1, %0 + %cond5 = select i1 %cmp1, i32 %3, i32 %2 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp ugt i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %2, i32 %3 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp ugt i32 %0, %4 + %cond15 = select i1 %cmp11, i32 %2, i32 %3 + store i32 %cond15, i32* @z4, align 4 + ret void +} + +define void @calc_selule() nounwind { +entry: + %0 = load i32* @a, align 4 + %1 = load i32* @b, align 4 + %cmp = icmp ule i32 %0, %1 + %2 = load i32* @t, align 4 + %3 = load i32* @f, align 4 + %cond = select i1 %cmp, i32 %2, i32 %3 + store i32 %cond, i32* @z1, align 4 +; 16: sltu ${{[0-9]+}}, ${{[0-9]+}} +; 16: bteqz .+4 +; 16: move ${{[0-9]+}}, ${{[0-9]+}} + %cmp1 = icmp ule i32 %1, %0 + %cond5 = select i1 %cmp1, i32 %3, i32 %2 + store i32 %cond5, i32* @z2, align 4 + %4 = load i32* @c, align 4 + %cmp6 = icmp ule i32 %4, %0 + %cond10 = select i1 %cmp6, i32 %2, i32 %3 + store i32 %cond10, i32* @z3, align 4 + %cmp11 = icmp ule i32 %0, %4 + %cond15 = select i1 %cmp11, i32 %2, i32 %3 + store i32 %cond15, i32* @z4, align 4 + ret void +} -- 2.7.4