diff options
author | Tom Stellard <tstellar@redhat.com> | 2019-04-22 22:31:50 +0000 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2019-04-22 22:31:50 +0000 |
commit | 257c01056b206b845957c08ede4b28a9600ece45 (patch) | |
tree | 2fd8f4c5b9252191abe182202aa842ac0edfbe0c | |
parent | Merging r356198: (diff) | |
download | llvm-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.cpp | 35 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/Fast-ISel/icmpbr1.ll | 3 | ||||
-rw-r--r-- | llvm/test/CodeGen/Mips/Fast-ISel/pr40325.ll | 23 |
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 +} |