diff options
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 50 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/minmax-fp.ll | 26 |
2 files changed, 57 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index c616e091290..feddbafa0d5 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3699,12 +3699,11 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2, Instruction::CastOps *CastOp) { CastInst *CI = dyn_cast<CastInst>(V1); Constant *C = dyn_cast<Constant>(V2); - CastInst *CI2 = dyn_cast<CastInst>(V2); if (!CI) return nullptr; *CastOp = CI->getOpcode(); - if (CI2) { + if (auto *CI2 = dyn_cast<CastInst>(V2)) { // If V1 and V2 are both the same cast from the same type, we can look // through V1. if (CI2->getOpcode() == CI->getOpcode() && @@ -3715,39 +3714,52 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2, 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 - // back to the original value. - if (ConstantExpr::getSExt(T, C->getType()) == C) - return T; - return nullptr; - } if (isa<ZExtInst>(CI) && CmpI->isUnsigned()) return ConstantExpr::getTrunc(C, CI->getSrcTy()); if (isa<TruncInst>(CI)) return ConstantExpr::getIntegerCast(C, CI->getSrcTy(), CmpI->isSigned()); + if (isa<FPTruncInst>(CI)) + return ConstantExpr::getFPExtend(C, CI->getSrcTy(), true); + + if (isa<FPExtInst>(CI)) + return ConstantExpr::getFPTrunc(C, CI->getSrcTy(), true); + + // Sophisticated constants can have values which we cannot easily reason + // about. Skip them for the fp<->int case. + if (isa<ConstantExpr>(C)) + return nullptr; + + Constant *CastedTo = nullptr; + + // This is only valid if the truncated value can be sign-extended + // back to the original value. + if (isa<SExtInst>(CI) && CmpI->isSigned()) + CastedTo = ConstantExpr::getTrunc(C, CI->getSrcTy(), true); + if (isa<FPToUIInst>(CI)) - return ConstantExpr::getUIToFP(C, CI->getSrcTy(), true); + CastedTo = ConstantExpr::getUIToFP(C, CI->getSrcTy(), true); if (isa<FPToSIInst>(CI)) - return ConstantExpr::getSIToFP(C, CI->getSrcTy(), true); + CastedTo = ConstantExpr::getSIToFP(C, CI->getSrcTy(), true); if (isa<UIToFPInst>(CI)) - return ConstantExpr::getFPToUI(C, CI->getSrcTy(), true); + CastedTo = ConstantExpr::getFPToUI(C, CI->getSrcTy(), true); if (isa<SIToFPInst>(CI)) - return ConstantExpr::getFPToSI(C, CI->getSrcTy(), true); + CastedTo = ConstantExpr::getFPToSI(C, CI->getSrcTy(), true); - if (isa<FPTruncInst>(CI)) - return ConstantExpr::getFPExtend(C, CI->getSrcTy(), true); + if (!CastedTo) + return nullptr; - if (isa<FPExtInst>(CI)) - return ConstantExpr::getFPTrunc(C, CI->getSrcTy(), true); + Constant *CastedBack = + ConstantExpr::getCast(CI->getOpcode(), CastedTo, C->getType(), true); + // Make sure the cast doesn't lose any information. + if (CastedBack != C) + return nullptr; - return nullptr; + return CastedTo; } SelectPatternResult llvm::matchSelectPattern(Value *V, diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll index b90afe3405f..b6eb1bb6834 100644 --- a/llvm/test/Transforms/InstCombine/minmax-fp.ll +++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll @@ -154,3 +154,29 @@ define i8 @t15(float %a) { %3 = select i1 %1, i8 %2, i8 0 ret i8 %3 } + +; CHECK-LABEL: @t16 +; CHECK: %[[cmp:.*]] = icmp sgt i32 %x, 0 +; CHECK: %[[cst:.*]] = sitofp i32 %x to double +; CHECK: %[[sel:.*]] = select i1 %[[cmp]], double %[[cst]], double 5.000000e-01 +; CHECK: ret double %[[sel]] +define double @t16(i32 %x) { +entry: + %cmp = icmp sgt i32 %x, 0 + %cst = sitofp i32 %x to double + %sel = select i1 %cmp, double %cst, double 5.000000e-01 + ret double %sel +} + +; CHECK-LABEL: @t17 +; CHECK: %[[cmp:.*]] = icmp sgt i32 %x, 2 +; CHECK: %[[sel:.*]] = select i1 %[[cmp]], i32 %x, i32 2 +; CHECK: %[[cst:.*]] = sitofp i32 %[[sel]] to double +; CHECK: ret double %[[cst]] +define double @t17(i32 %x) { +entry: + %cmp = icmp sgt i32 %x, 2 + %cst = sitofp i32 %x to double + %sel = select i1 %cmp, double %cst, double 2.0 + ret double %sel +} |

