mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-23 19:17:17 +00:00
[ValueTracking] Look through casts when both operands are casts.
We only looked through casts when one operand was a constant. We can also look through casts when both operands are non-constant, but both are in fact the same cast type. For example: %1 = icmp ult i8 %a, %b %2 = zext i8 %a to i32 %3 = zext i8 %b to i32 %4 = select i1 %1, i32 %2, i32 %3 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246678 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a1bc1c274d
commit
983cfca15d
@ -3750,14 +3750,26 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
|
||||
return {SPF_UNKNOWN, SPNB_NA, false};
|
||||
}
|
||||
|
||||
static Constant *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
|
||||
Instruction::CastOps *CastOp) {
|
||||
static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
|
||||
Instruction::CastOps *CastOp) {
|
||||
CastInst *CI = dyn_cast<CastInst>(V1);
|
||||
Constant *C = dyn_cast<Constant>(V2);
|
||||
if (!CI || !C)
|
||||
CastInst *CI2 = dyn_cast<CastInst>(V2);
|
||||
if (!CI)
|
||||
return nullptr;
|
||||
*CastOp = CI->getOpcode();
|
||||
|
||||
if (CI2) {
|
||||
// If V1 and V2 are both the same cast from the same type, we can look
|
||||
// through V1.
|
||||
if (CI2->getOpcode() == CI->getOpcode() &&
|
||||
CI2->getSrcTy() == CI->getSrcTy())
|
||||
return CI2->getOperand(0);
|
||||
return nullptr;
|
||||
} else if (!C) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (isa<SExtInst>(CI) && CmpI->isSigned()) {
|
||||
Constant *T = ConstantExpr::getTrunc(C, CI->getSrcTy());
|
||||
// This is only valid if the truncated value can be sign-extended
|
||||
@ -3817,11 +3829,11 @@ SelectPatternResult llvm::matchSelectPattern(Value *V,
|
||||
|
||||
// Deal with type mismatches.
|
||||
if (CastOp && CmpLHS->getType() != TrueVal->getType()) {
|
||||
if (Constant *C = lookThroughCast(CmpI, TrueVal, FalseVal, CastOp))
|
||||
if (Value *C = lookThroughCast(CmpI, TrueVal, FalseVal, CastOp))
|
||||
return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS,
|
||||
cast<CastInst>(TrueVal)->getOperand(0), C,
|
||||
LHS, RHS);
|
||||
if (Constant *C = lookThroughCast(CmpI, FalseVal, TrueVal, CastOp))
|
||||
if (Value *C = lookThroughCast(CmpI, FalseVal, TrueVal, CastOp))
|
||||
return ::matchSelectPattern(Pred, FMF, CmpLHS, CmpRHS,
|
||||
C, cast<CastInst>(FalseVal)->getOperand(0),
|
||||
LHS, RHS);
|
||||
|
@ -146,3 +146,45 @@ TEST_F(MatchSelectPatternTest, FMinConstantZeroNsz) {
|
||||
// But this should be, because we've ignored signed zeroes.
|
||||
expectPattern({SPF_FMINNUM, SPNB_RETURNS_OTHER, true});
|
||||
}
|
||||
|
||||
TEST_F(MatchSelectPatternTest, DoubleCastU) {
|
||||
parseAssembly(
|
||||
"define i32 @test(i8 %a, i8 %b) {\n"
|
||||
" %1 = icmp ult i8 %a, %b\n"
|
||||
" %2 = zext i8 %a to i32\n"
|
||||
" %3 = zext i8 %b to i32\n"
|
||||
" %A = select i1 %1, i32 %2, i32 %3\n"
|
||||
" ret i32 %A\n"
|
||||
"}\n");
|
||||
// We should be able to look through the situation where we cast both operands
|
||||
// to the select.
|
||||
expectPattern({SPF_UMIN, SPNB_NA, false});
|
||||
}
|
||||
|
||||
TEST_F(MatchSelectPatternTest, DoubleCastS) {
|
||||
parseAssembly(
|
||||
"define i32 @test(i8 %a, i8 %b) {\n"
|
||||
" %1 = icmp slt i8 %a, %b\n"
|
||||
" %2 = sext i8 %a to i32\n"
|
||||
" %3 = sext i8 %b to i32\n"
|
||||
" %A = select i1 %1, i32 %2, i32 %3\n"
|
||||
" ret i32 %A\n"
|
||||
"}\n");
|
||||
// We should be able to look through the situation where we cast both operands
|
||||
// to the select.
|
||||
expectPattern({SPF_SMIN, SPNB_NA, false});
|
||||
}
|
||||
|
||||
TEST_F(MatchSelectPatternTest, DoubleCastBad) {
|
||||
parseAssembly(
|
||||
"define i32 @test(i8 %a, i8 %b) {\n"
|
||||
" %1 = icmp ult i8 %a, %b\n"
|
||||
" %2 = zext i8 %a to i32\n"
|
||||
" %3 = sext i8 %b to i32\n"
|
||||
" %A = select i1 %1, i32 %2, i32 %3\n"
|
||||
" ret i32 %A\n"
|
||||
"}\n");
|
||||
// We should be able to look through the situation where we cast both operands
|
||||
// to the select.
|
||||
expectPattern({SPF_UNKNOWN, SPNB_NA, false});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user