summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@redhat.com>2019-04-22 22:31:50 +0000
committerTom Stellard <tstellar@redhat.com>2019-04-22 22:31:50 +0000
commit257c01056b206b845957c08ede4b28a9600ece45 (patch)
tree2fd8f4c5b9252191abe182202aa842ac0edfbe0c
parentMerging r356198: (diff)
downloadllvm-project-257c01056b206b845957c08ede4b28a9600ece45.tar.gz
llvm-project-257c01056b206b845957c08ede4b28a9600ece45.tar.bz2
llvm-project-257c01056b206b845957c08ede4b28a9600ece45.zip
Merging r354808:
------------------------------------------------------------------------ r354808 | nikic | 2019-02-25 10:54:17 -0800 (Mon, 25 Feb 2019) | 11 lines [Mips] Fix missing masking in fast-isel of br (PR40325) Fixes https://bugs.llvm.org/show_bug.cgi?id=40325 by zero extending (and x, 1) the condition before branching on it. To avoid regressing trivial cases, I'm combining emission of cmp+br sequences for the single-use + same block case (similar to what we do in x86). icmpbr1.ll still regresses due to the cross-bb usage of the condition. Differential Revision: https://reviews.llvm.org/D58576 ------------------------------------------------------------------------ llvm-svn: 358925
-rw-r--r--llvm/lib/Target/Mips/MipsFastISel.cpp35
-rw-r--r--llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll3
-rw-r--r--llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll23
3 files changed, 49 insertions, 12 deletions
diff --git a/llvm/lib/Target/Mips/MipsFastISel.cpp b/llvm/lib/Target/Mips/MipsFastISel.cpp
index a18416b9e861..168750b2cba9 100644
--- a/llvm/lib/Target/Mips/MipsFastISel.cpp
+++ b/llvm/lib/Target/Mips/MipsFastISel.cpp
@@ -954,21 +954,34 @@ bool MipsFastISel::selectBranch(const Instruction *I) {
//
MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
- // For now, just try the simplest case where it's fed by a compare.
+
+ // Fold the common case of a conditional branch with a comparison
+ // in the same block.
+ unsigned ZExtCondReg = 0;
if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
- MVT CIMVT =
- TLI.getValueType(DL, CI->getOperand(0)->getType(), true).getSimpleVT();
- if (CIMVT == MVT::i1)
+ if (CI->hasOneUse() && CI->getParent() == I->getParent()) {
+ ZExtCondReg = createResultReg(&Mips::GPR32RegClass);
+ if (!emitCmp(ZExtCondReg, CI))
+ return false;
+ }
+ }
+
+ // For the general case, we need to mask with 1.
+ if (ZExtCondReg == 0) {
+ unsigned CondReg = getRegForValue(BI->getCondition());
+ if (CondReg == 0)
return false;
- unsigned CondReg = getRegForValue(CI);
- BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ))
- .addReg(CondReg)
- .addMBB(TBB);
- finishCondBranch(BI->getParent(), TBB, FBB);
- return true;
+ ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true);
+ if (ZExtCondReg == 0)
+ return false;
}
- return false;
+
+ BuildMI(*BrBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::BGTZ))
+ .addReg(ZExtCondReg)
+ .addMBB(TBB);
+ finishCondBranch(BI->getParent(), TBB, FBB);
+ return true;
}
bool MipsFastISel::selectCmp(const Instruction *I) {
diff --git a/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll b/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll
index ef8e1c2b0140..e44ab36532c5 100644
--- a/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll
+++ b/llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll
@@ -17,7 +17,8 @@ bb0:
bb1:
; CHECK: # %bb.1: # %bb1
; CHECK-NEXT: lw $[[REG2:[0-9]+]], [[SPILL]]($sp) # 4-byte Folded Reload
-; CHECK-NEXT: bgtz $[[REG2]], $BB0_3
+; CHECK-NEXT: andi $[[REG3:[0-9]+]], $[[REG2]], 1
+; CHECK-NEXT: bgtz $[[REG3]], $BB0_3
br i1 %2, label %bb2, label %bb3
bb2:
; CHECK: $BB0_3: # %bb2
diff --git a/llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll b/llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll
new file mode 100644
index 000000000000..a9ce70fe8afc
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=mipsel -relocation-model=pic -O0 -mcpu=mips32 < %s | FileCheck %s
+
+define void @test(i32 %x, i1* %p) nounwind {
+; CHECK-LABEL: test:
+; CHECK: # %bb.0:
+; CHECK-NEXT: move $1, $4
+; CHECK-NEXT: andi $4, $4, 1
+; CHECK-NEXT: sb $4, 0($5)
+; CHECK-NEXT: andi $1, $1, 1
+; CHECK-NEXT: bgtz $1, $BB0_1
+; CHECK-NEXT: nop
+; CHECK-NEXT: # %bb.1: # %foo
+; CHECK-NEXT: jr $ra
+; CHECK-NEXT: nop
+ %y = and i32 %x, 1
+ %c = icmp eq i32 %y, 1
+ store i1 %c, i1* %p
+ br i1 %c, label %foo, label %foo
+
+foo:
+ ret void
+}