Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5108,7 +5108,7 @@ // same as SimplifySelectCC. N0isZero()) { + EVT IntVT = N0.getValueType(); + EVT FPVT = N0.getOperand(0).getValueType(); + if (FPVT.isSimple()) { + Type *InputTy = FPVT.getTypeForEVT(*DAG.getContext())->getScalarType(); + const fltSemantics &Semantics = InputTy->getFltSemantics(); + uint32_t MinBitWidth = + APFloatBase::semanticsMaxExponent(Semantics) + 2; + if (IntVT.getSizeInBits() >= MinBitWidth) { + Unsigned = true; + BW = PowerOf2Ceil(MinBitWidth); + return N0; + } + } + } + } + SDValue N00, N01, N02, N03; ISD::CondCode N0CC; switch (N0.getOpcode()) { @@ -5194,7 +5215,7 @@ SelectionDAG &DAG) { unsigned BW; bool Unsigned; - SDValue Fp = isSaturatingMinMax(N0, N1, N2, N3, CC, BW, Unsigned); + SDValue Fp = isSaturatingMinMax(N0, N1, N2, N3, CC, BW, Unsigned, DAG); if (!Fp || Fp.getOpcode() != ISD::FP_TO_SINT) return SDValue(); EVT FPVT = Fp.getOperand(0).getValueType(); Index: llvm/test/CodeGen/WebAssembly/fpclamptosat.ll =================================================================== --- llvm/test/CodeGen/WebAssembly/fpclamptosat.ll +++ llvm/test/CodeGen/WebAssembly/fpclamptosat.ll @@ -191,19 +191,11 @@ define i32 @ustest_f16i32_cse(half %x) { ; CHECK-LABEL: ustest_f16i32_cse: ; CHECK: .functype ustest_f16i32_cse (f32) -> (i32) -; CHECK-NEXT: .local i64 ; CHECK-NEXT: # %bb.0: # %entry ; CHECK-NEXT: local.get 0 ; CHECK-NEXT: call __truncsfhf2 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: i64.trunc_sat_f32_s -; CHECK-NEXT: local.tee 1 -; CHECK-NEXT: i64.const 0 -; CHECK-NEXT: local.get 1 -; CHECK-NEXT: i64.const 0 -; CHECK-NEXT: i64.gt_s -; CHECK-NEXT: i64.select -; CHECK-NEXT: i32.wrap_i64 +; CHECK-NEXT: i32.trunc_sat_f32_u ; CHECK-NEXT: # fallthrough-return entry: %conv = fptosi half %x to i64 @@ -485,18 +477,11 @@ define i16 @ustest_f16i16_cse(half %x) { ; CHECK-LABEL: ustest_f16i16_cse: ; CHECK: .functype ustest_f16i16_cse (f32) -> (i32) -; CHECK-NEXT: .local i32 ; CHECK-NEXT: # %bb.0: # %entry ; CHECK-NEXT: local.get 0 ; CHECK-NEXT: call __truncsfhf2 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: i32.trunc_sat_f32_s -; CHECK-NEXT: local.tee 1 -; CHECK-NEXT: i32.const 0 -; CHECK-NEXT: local.get 1 -; CHECK-NEXT: i32.const 0 -; CHECK-NEXT: i32.gt_s -; CHECK-NEXT: i32.select +; CHECK-NEXT: i32.trunc_sat_f32_u ; CHECK-NEXT: # fallthrough-return entry: %conv = fptosi half %x to i32 @@ -1035,19 +1020,11 @@ define i32 @ustest_f16i32_mm_cse(half %x) { ; CHECK-LABEL: ustest_f16i32_mm_cse: ; CHECK: .functype ustest_f16i32_mm_cse (f32) -> (i32) -; CHECK-NEXT: .local i64 ; CHECK-NEXT: # %bb.0: # %entry ; CHECK-NEXT: local.get 0 ; CHECK-NEXT: call __truncsfhf2 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: i64.trunc_sat_f32_s -; CHECK-NEXT: local.tee 1 -; CHECK-NEXT: i64.const 0 -; CHECK-NEXT: local.get 1 -; CHECK-NEXT: i64.const 0 -; CHECK-NEXT: i64.gt_s -; CHECK-NEXT: i64.select -; CHECK-NEXT: i32.wrap_i64 +; CHECK-NEXT: i32.trunc_sat_f32_u ; CHECK-NEXT: # fallthrough-return entry: %conv = fptosi half %x to i64 @@ -1298,18 +1275,11 @@ define i16 @ustest_f16i16_mm_cse(half %x) { ; CHECK-LABEL: ustest_f16i16_mm_cse: ; CHECK: .functype ustest_f16i16_mm_cse (f32) -> (i32) -; CHECK-NEXT: .local i32 ; CHECK-NEXT: # %bb.0: # %entry ; CHECK-NEXT: local.get 0 ; CHECK-NEXT: call __truncsfhf2 ; CHECK-NEXT: call __extendhfsf2 -; CHECK-NEXT: i32.trunc_sat_f32_s -; CHECK-NEXT: local.tee 1 -; CHECK-NEXT: i32.const 0 -; CHECK-NEXT: local.get 1 -; CHECK-NEXT: i32.const 0 -; CHECK-NEXT: i32.gt_s -; CHECK-NEXT: i32.select +; CHECK-NEXT: i32.trunc_sat_f32_u ; CHECK-NEXT: # fallthrough-return entry: %conv = fptosi half %x to i32