| 2091 | |
| 2092 | namespace { |
| 2093 | StatusOr<std::unique_ptr<HloInstruction>> MinMaxToClamp( |
| 2094 | HloInstruction* clamp_lower_bound_bcast, HloInstruction* to_clamp, |
| 2095 | HloInstruction* clamp_upper_bound_bcast) { |
| 2096 | HloInstruction* clamp_lower_bound; |
| 2097 | CHECK(Match(clamp_lower_bound_bcast, |
| 2098 | m::Broadcast(m::ConstantEffectiveScalar(&clamp_lower_bound)))) |
| 2099 | << clamp_lower_bound_bcast->ToString(); |
| 2100 | |
| 2101 | HloInstruction* clamp_upper_bound; |
| 2102 | CHECK(Match(clamp_upper_bound_bcast, |
| 2103 | m::Broadcast(m::ConstantEffectiveScalar(&clamp_upper_bound)))) |
| 2104 | << clamp_upper_bound_bcast->ToString(); |
| 2105 | |
| 2106 | const Literal& lower_bound = |
| 2107 | Cast<HloConstantInstruction>(clamp_lower_bound)->literal(); |
| 2108 | const Literal& upper_bound = |
| 2109 | Cast<HloConstantInstruction>(clamp_upper_bound)->literal(); |
| 2110 | |
| 2111 | std::unique_ptr<HloInstruction> lower_bound_instr = |
| 2112 | HloInstruction::CreateConstant(lower_bound.Clone()); |
| 2113 | std::unique_ptr<HloInstruction> upper_bound_instr = |
| 2114 | HloInstruction::CreateConstant(upper_bound.Clone()); |
| 2115 | |
| 2116 | std::unique_ptr<HloInstruction> cloned_instruction = |
| 2117 | HloInstruction::CreateCompare( |
| 2118 | ShapeUtil::ChangeElementType(lower_bound_instr->shape(), PRED), |
| 2119 | lower_bound_instr.get(), upper_bound_instr.get(), |
| 2120 | ComparisonDirection::kLt); |
| 2121 | |
| 2122 | HloEvaluator evaluator; |
| 2123 | TF_ASSIGN_OR_RETURN(auto result, |
| 2124 | evaluator.Evaluate(cloned_instruction.get())); |
| 2125 | if (result.IsAll(true)) { |
| 2126 | return HloInstruction::CreateTernary(to_clamp->shape(), HloOpcode::kClamp, |
| 2127 | clamp_lower_bound_bcast, to_clamp, |
| 2128 | clamp_upper_bound_bcast); |
| 2129 | } |
| 2130 | return std::unique_ptr<HloInstruction>(); |
| 2131 | } |
| 2132 | } // namespace |
| 2133 | |
| 2134 | Status AlgebraicSimplifierVisitor::HandleMaximum(HloInstruction* maximum) { |