From 03676dc96915203efd4f0c4a1f04a7b54c4f6370 Mon Sep 17 00:00:00 2001 From: Simon Dardis Date: Tue, 31 May 2016 09:54:55 +0000 Subject: [PATCH] [mips] bnec/beqc register constraint fix beqc and bnec cannot have $rs == $rt. Inhibit compact branch creation if that would occur. Reviewers: vkalintiris, dsanders Differential Revision: http://reviews.llvm.org/D20624 llvm-svn: 271260 --- llvm/lib/Target/Mips/MipsInstrInfo.cpp | 10 ++-- .../beqc-bnec-register-constraint.ll | 55 +++++++++++++++++++ 2 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index 1da879b114e1..02bc3f77d949 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -301,13 +301,15 @@ unsigned MipsInstrInfo::getEquivalentCompactForm( case Mips::BEQ: if (canUseShortMicroMipsCTI) return Mips::BEQZC_MM; - else - return Mips::BEQC; + else if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) + return 0; + return Mips::BEQC; case Mips::BNE: if (canUseShortMicroMipsCTI) return Mips::BNEZC_MM; - else - return Mips::BNEC; + else if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) + return 0; + return Mips::BNEC; case Mips::BGE: if (I->getOperand(0).getReg() == I->getOperand(1).getReg()) return 0; diff --git a/llvm/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll b/llvm/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll new file mode 100644 index 000000000000..3cec194a3786 --- /dev/null +++ b/llvm/test/CodeGen/Mips/compactbranches/beqc-bnec-register-constraint.ll @@ -0,0 +1,55 @@ +; RUN: llc -march=mips -mcpu=mips32r6 -O1 -start-after=dwarfehprepare < %s | FileCheck %s + +; beqc/bnec have the constraint that $rs < $rt && $rs != 0 && $rt != 0 +; Cases where $rs == 0 and $rt != 0 should be transformed into beqzc/bnezc. +; Cases where $rs > $rt can have the operands swapped as ==,!= are commutative. + +; Cases where beq & bne where $rs == $rt have to inhibited from being turned +; into compact branches but arguably should not occur. This test covers the +; $rs == $rt case. + +; Starting from dwarf exception handling preparation skips optimizations that +; may simplify out the crucical bnec $4, $4 instruction. + +define internal void @_ZL14TestRemoveLastv(i32* %alist.sroa.0.4) { +entry: + %ascevgep = getelementptr i32, i32* %alist.sroa.0.4, i64 99 + br label %do.body121 + +for.cond117: + %alsr.iv.next = add nsw i32 %alsr.iv, -1 + %ascevgep340 = getelementptr i32, i32* %alsr.iv339, i64 -1 + %acmp118 = icmp sgt i32 %alsr.iv.next, 0 + br i1 %acmp118, label %do.body121, label %if.then143 + +do.body121: + %alsr.iv339 = phi i32* [ %ascevgep, %entry ], [ %ascevgep340, %for.cond117 ] + %alsr.iv = phi i32 [ 100, %entry ], [ %alsr.iv.next, %for.cond117 ] + %a9 = add i32 %alsr.iv, -1 + %alnot124 = icmp eq i32 %alsr.iv, %alsr.iv + br i1 %alnot124, label %do.body134, label %if.then143, !prof !11 + +do.body134: + %a10 = add i32 %alsr.iv, -1 + %a11 = load i32, i32* %alsr.iv339, align 4, !tbaa !5 +; CHECK-NOT: bnec $[[R0:[0-9]+]], $[[R0]] +; CHECK-NOT: beqc $[[R1:[0-9]+]], $[[R1]] + %alnot137 = icmp eq i32 %a9, %a11 + br i1 %alnot137, label %do.end146, label %if.then143, !prof !11 + +if.then143: + ret void + unreachable + +do.end146: + %alnot151 = icmp eq i32 %a9, %a10 + br i1 %alnot151, label %for.cond117, label %if.then143, !prof !11 + +} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C++ TBAA"} +!5 = !{!6, !6, i64 0} +!6 = !{!"int", !3, i64 0} +!11 = !{!"branch_weights", i32 2000, i32 1} +!12 = !{!"branch_weights", i32 -388717296, i32 7818360} +