Index: llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td @@ -58,6 +58,15 @@ return false; }]>; +def PowerOf2LO_i32 : PatLeaf<(imm), [{ + if (N->getValueType(0) == MVT::i32) { + uint64_t Imm = N->getZExtValue(); + return isPowerOf2_32(Imm) && isUInt<32>(Imm); + } + else + return false; +}]>; + def assertzext_lt_i32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ return cast(N->getOperand(1))->getVT().bitsLT(MVT::i32); }]>; @@ -709,6 +718,12 @@ (BBIT1 i64:$lhs, (Log2LO PowerOf2LO:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS; def : MipsPat<(brcond (i32 (setne (and i64:$lhs, PowerOf2HI:$mask), 0)), bb:$dst), (BBIT132 i64:$lhs, (Log2HI PowerOf2HI:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS; +def : MipsPat<(brcond (i32 (seteq (and i32:$lhs, PowerOf2LO_i32:$mask), 0)), bb:$dst), + (BBIT0 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), i32:$lhs, sub_32), + (Log2LO PowerOf2LO_i32:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS; +def : MipsPat<(brcond (i32 (setne (and i32:$lhs, PowerOf2LO_i32:$mask), 0)), bb:$dst), + (BBIT1 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), i32:$lhs, sub_32), + (Log2LO PowerOf2LO_i32:$mask), bb:$dst)>, ASE_MIPS64_CNMIPS; // Atomic load patterns. def : MipsPat<(atomic_load_8 addr:$a), (LB64 addr:$a)>; Index: llvm/trunk/test/CodeGen/Mips/octeon.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/octeon.ll +++ llvm/trunk/test/CodeGen/Mips/octeon.ll @@ -164,3 +164,59 @@ endif: ret i64 12 } + +; extern void foo(void); +; long long var = 7; +; void bbit0i32 () { +; if ((var & 0x2)) { +; foo(); +; } +; } +; +; void bbit1i32() { +; if (!(var & 0x2)) { +; foo(); +; } +; } + +@var = local_unnamed_addr global i64 7, align 8 + +define void @bbit0i32() local_unnamed_addr { +entry: +; ALL-LABEL: bbit0i32: +; OCTEON: bbit0 $1, 1, [[BB0:(\$|\.L)BB[0-9_]+]] +; OCTEON-PIC-NOT: b {{[[:space:]].*}} +; OCTEON-NOT: j {{[[:space:]].*}} + %0 = load i64, i64* @var, align 8 + %and = and i64 %0, 2 + %tobool = icmp eq i64 %and, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + tail call void @foo() #2 + br label %if.end + +if.end: ; preds = %entry, %if.then + ret void +} + +declare void @foo() local_unnamed_addr + +define void @bbit1i32() local_unnamed_addr { +entry: +; ALL-LABEL: bbit1i32: +; OCTEON: bbit1 $1, 1, [[BB0:(\$|\.L)BB[0-9_]+]] +; OCTEON-PIC-NOT: b {{[[:space:]].*}} +; OCTEON-NOT: j {{[[:space:]].*}} + %0 = load i64, i64* @var, align 8 + %and = and i64 %0, 2 + %tobool = icmp eq i64 %and, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void @foo() #2 + br label %if.end + +if.end: ; preds = %entry, %if.then + ret void +}