forked from OSchip/llvm-project
[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: 354808
This commit is contained in:
parent
6bcfa1c419
commit
fcbd7f6495
|
@ -953,21 +953,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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue