/// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form: /// SPF2(SPF1(A, B), C) Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C) { if (C == A || C == B) { // MAX(MAX(A, B), B) -> MAX(A, B) // MIN(MIN(a, b), a) -> MIN(a, b) if (SPF1 == SPF2) return ReplaceInstUsesWith(Outer, Inner); // MAX(MIN(a, b), a) -> a // MIN(MAX(a, b), a) -> a if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) || (SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) || (SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) || (SPF1 == SPF_UMAX && SPF2 == SPF_UMIN)) return ReplaceInstUsesWith(Outer, C); } if (SPF1 == SPF2) { if (ConstantInt *CB = dyn_cast<ConstantInt>(B)) { if (ConstantInt *CC = dyn_cast<ConstantInt>(C)) { APInt ACB = CB->getValue(); APInt ACC = CC->getValue(); // MIN(MIN(A, 23), 97) -> MIN(A, 23) // MAX(MAX(A, 97), 23) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ule(ACC)) || (SPF1 == SPF_SMIN && ACB.sle(ACC)) || (SPF1 == SPF_UMAX && ACB.uge(ACC)) || (SPF1 == SPF_SMAX && ACB.sge(ACC))) return ReplaceInstUsesWith(Outer, Inner); // MIN(MIN(A, 97), 23) -> MIN(A, 23) // MAX(MAX(A, 23), 97) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ugt(ACC)) || (SPF1 == SPF_SMIN && ACB.sgt(ACC)) || (SPF1 == SPF_UMAX && ACB.ult(ACC)) || (SPF1 == SPF_SMAX && ACB.slt(ACC))) { Outer.replaceUsesOfWith(Inner, A); return &Outer; } } } } return nullptr; }
APInt swift::constantFoldComparison(APInt lhs, APInt rhs, BuiltinValueKind ID) { bool result; switch (ID) { default: llvm_unreachable("Invalid integer compare kind"); case BuiltinValueKind::ICMP_EQ: result = lhs == rhs; break; case BuiltinValueKind::ICMP_NE: result = lhs != rhs; break; case BuiltinValueKind::ICMP_SLT: result = lhs.slt(rhs); break; case BuiltinValueKind::ICMP_SGT: result = lhs.sgt(rhs); break; case BuiltinValueKind::ICMP_SLE: result = lhs.sle(rhs); break; case BuiltinValueKind::ICMP_SGE: result = lhs.sge(rhs); break; case BuiltinValueKind::ICMP_ULT: result = lhs.ult(rhs); break; case BuiltinValueKind::ICMP_UGT: result = lhs.ugt(rhs); break; case BuiltinValueKind::ICMP_ULE: result = lhs.ule(rhs); break; case BuiltinValueKind::ICMP_UGE: result = lhs.uge(rhs); break; } return APInt(1, result); }
/// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form: /// SPF2(SPF1(A, B), C) Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C) { if (C == A || C == B) { // MAX(MAX(A, B), B) -> MAX(A, B) // MIN(MIN(a, b), a) -> MIN(a, b) if (SPF1 == SPF2) return ReplaceInstUsesWith(Outer, Inner); // MAX(MIN(a, b), a) -> a // MIN(MAX(a, b), a) -> a if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) || (SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) || (SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) || (SPF1 == SPF_UMAX && SPF2 == SPF_UMIN)) return ReplaceInstUsesWith(Outer, C); } if (SPF1 == SPF2) { if (ConstantInt *CB = dyn_cast<ConstantInt>(B)) { if (ConstantInt *CC = dyn_cast<ConstantInt>(C)) { APInt ACB = CB->getValue(); APInt ACC = CC->getValue(); // MIN(MIN(A, 23), 97) -> MIN(A, 23) // MAX(MAX(A, 97), 23) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ule(ACC)) || (SPF1 == SPF_SMIN && ACB.sle(ACC)) || (SPF1 == SPF_UMAX && ACB.uge(ACC)) || (SPF1 == SPF_SMAX && ACB.sge(ACC))) return ReplaceInstUsesWith(Outer, Inner); // MIN(MIN(A, 97), 23) -> MIN(A, 23) // MAX(MAX(A, 23), 97) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ugt(ACC)) || (SPF1 == SPF_SMIN && ACB.sgt(ACC)) || (SPF1 == SPF_UMAX && ACB.ult(ACC)) || (SPF1 == SPF_SMAX && ACB.slt(ACC))) { Outer.replaceUsesOfWith(Inner, A); return &Outer; } } } } // ABS(ABS(X)) -> ABS(X) // NABS(NABS(X)) -> NABS(X) if (SPF1 == SPF2 && (SPF1 == SPF_ABS || SPF1 == SPF_NABS)) { return ReplaceInstUsesWith(Outer, Inner); } // ABS(NABS(X)) -> ABS(X) // NABS(ABS(X)) -> NABS(X) if ((SPF1 == SPF_ABS && SPF2 == SPF_NABS) || (SPF1 == SPF_NABS && SPF2 == SPF_ABS)) { SelectInst *SI = cast<SelectInst>(Inner); Value *NewSI = Builder->CreateSelect( SI->getCondition(), SI->getFalseValue(), SI->getTrueValue()); return ReplaceInstUsesWith(Outer, NewSI); } return nullptr; }