Index: llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -247,6 +247,11 @@ Res = NPN; break; } + case Instruction::FPToUI: + case Instruction::FPToSI: + Res = CastInst::Create( + static_cast(Opc), I->getOperand(0), Ty); + break; default: // TODO: Can handle more cases here. llvm_unreachable("Unreachable!"); @@ -491,6 +496,15 @@ return false; return true; } + case Instruction::FPToUI: + case Instruction::FPToSI: { + Type *InputTy = I->getOperand(0)->getType()->getScalarType(); + uint32_t BitWidth = Ty->getScalarSizeInBits(); + uint32_t MinBitWidth = InputTy->getScalarSizeInBits() + 1; + if (InputTy->isHalfTy() && I->getOpcode() == Instruction::FPToUI) + MinBitWidth = 16; + return BitWidth >= MinBitWidth; + } default: // TODO: Can handle more cases here. break; Index: llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll =================================================================== --- llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll +++ llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll @@ -27,9 +27,8 @@ define i16 @half_fptoui_i17_i16(half %x) { ; CHECK-LABEL: @half_fptoui_i17_i16( -; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i17 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i17 [[CONV]] to i16 -; CHECK-NEXT: ret i16 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %conv = fptoui half %x to i17 %conv.1 = trunc i17 %conv to i16 @@ -38,9 +37,8 @@ define i16 @half_fptoui_i17_i16_noundef(half noundef %x) { ; CHECK-LABEL: @half_fptoui_i17_i16_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i17 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i17 [[CONV]] to i16 -; CHECK-NEXT: ret i16 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %conv = fptoui half %x to i17 %conv.1 = trunc i17 %conv to i16 @@ -49,9 +47,8 @@ define i16 @half_fptoui_i32_i16(half %x) { ; CHECK-LABEL: @half_fptoui_i32_i16( -; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i32 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i32 [[CONV]] to i16 -; CHECK-NEXT: ret i16 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %conv = fptoui half %x to i32 %conv.1 = trunc i32 %conv to i16 @@ -60,9 +57,8 @@ define i16 @half_fptoui_i32_i16_noundef(half noundef %x) { ; CHECK-LABEL: @half_fptoui_i32_i16_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i32 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i32 [[CONV]] to i16 -; CHECK-NEXT: ret i16 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] ; %conv = fptoui half %x to i32 %conv.1 = trunc i32 %conv to i16 @@ -95,9 +91,8 @@ define <4 x i16> @half_fptoui_4xi32_4xi16(<4 x half> %x) { ; CHECK-LABEL: @half_fptoui_4xi32_4xi16( -; CHECK-NEXT: [[CONV:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i32> -; CHECK-NEXT: [[CONV_1:%.*]] = trunc <4 x i32> [[CONV]] to <4 x i16> -; CHECK-NEXT: ret <4 x i16> [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i16> +; CHECK-NEXT: ret <4 x i16> [[CONV]] ; %conv = fptoui <4 x half> %x to <4 x i32> %conv.1 = trunc <4 x i32> %conv to <4 x i16> @@ -106,9 +101,8 @@ define <4 x i16> @half_fptoui_4xi32_4xi16_noundef(<4 x half> noundef %x) { ; CHECK-LABEL: @half_fptoui_4xi32_4xi16_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i32> -; CHECK-NEXT: [[CONV_1:%.*]] = trunc <4 x i32> [[CONV]] to <4 x i16> -; CHECK-NEXT: ret <4 x i16> [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i16> +; CHECK-NEXT: ret <4 x i16> [[CONV]] ; %conv = fptoui <4 x half> %x to <4 x i32> %conv.1 = trunc <4 x i32> %conv to <4 x i16> @@ -118,8 +112,8 @@ ; Negative test. define i31 @float_fptoui_i64_i31(float %x) { ; CHECK-LABEL: @float_fptoui_i64_i31( -; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i31 +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i62 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i62 [[CONV]] to i31 ; CHECK-NEXT: ret i31 [[CONV_1]] ; %conv = fptoui float %x to i64 @@ -130,8 +124,8 @@ ; Negative test. define i31 @float_fptoui_i64_i31_noundef(float noundef %x) { ; CHECK-LABEL: @float_fptoui_i64_i31_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i31 +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i62 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i62 [[CONV]] to i31 ; CHECK-NEXT: ret i31 [[CONV_1]] ; %conv = fptoui float %x to i64 @@ -165,9 +159,8 @@ define i33 @float_fptoui_i64_i33(float %x) { ; CHECK-LABEL: @float_fptoui_i64_i33( -; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i33 -; CHECK-NEXT: ret i33 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i33 +; CHECK-NEXT: ret i33 [[CONV]] ; %conv = fptoui float %x to i64 %conv.1 = trunc i64 %conv to i33 @@ -176,9 +169,8 @@ define i33 @float_fptoui_i64_i33_noundef(float noundef %x) { ; CHECK-LABEL: @float_fptoui_i64_i33_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i33 -; CHECK-NEXT: ret i33 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i33 +; CHECK-NEXT: ret i33 [[CONV]] ; %conv = fptoui float %x to i64 %conv.1 = trunc i64 %conv to i33 @@ -187,9 +179,8 @@ define i64 @float_fptoui_i128_i64(float %x) { ; CHECK-LABEL: @float_fptoui_i128_i64( -; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i128 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i128 [[CONV]] to i64 -; CHECK-NEXT: ret i64 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %conv = fptoui float %x to i128 %conv.1 = trunc i128 %conv to i64 @@ -198,9 +189,8 @@ define i64 @float_fptoui_i128_i64_noundef(float noundef %x) { ; CHECK-LABEL: @float_fptoui_i128_i64_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i128 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i128 [[CONV]] to i64 -; CHECK-NEXT: ret i64 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %conv = fptoui float %x to i128 %conv.1 = trunc i128 %conv to i64 @@ -305,9 +295,8 @@ define <4 x i32> @half_fptosi_4xi64_4xi32(<4 x half> %x) { ; CHECK-LABEL: @half_fptosi_4xi64_4xi32( -; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i64> -; CHECK-NEXT: [[CONV_1:%.*]] = trunc <4 x i64> [[CONV]] to <4 x i32> -; CHECK-NEXT: ret <4 x i32> [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i32> +; CHECK-NEXT: ret <4 x i32> [[CONV]] ; %conv = fptosi <4 x half> %x to <4 x i64> %conv.1 = trunc <4 x i64> %conv to <4 x i32> @@ -317,8 +306,8 @@ ; Negative test. define i31 @float_fptosi_i64_i31(float %x) { ; CHECK-LABEL: @float_fptosi_i64_i31( -; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i31 +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i62 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i62 [[CONV]] to i31 ; CHECK-NEXT: ret i31 [[CONV_1]] ; %conv = fptosi float %x to i64 @@ -329,8 +318,8 @@ ; Negative test. define i31 @float_fptosi_i64_i31_noundef(float noundef %x) { ; CHECK-LABEL: @float_fptosi_i64_i31_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i31 +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i62 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i62 [[CONV]] to i31 ; CHECK-NEXT: ret i31 [[CONV_1]] ; %conv = fptosi float %x to i64 @@ -364,9 +353,8 @@ define i33 @float_fptosi_i64_i33(float %x) { ; CHECK-LABEL: @float_fptosi_i64_i33( -; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i33 -; CHECK-NEXT: ret i33 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i33 +; CHECK-NEXT: ret i33 [[CONV]] ; %conv = fptosi float %x to i64 %conv.1 = trunc i64 %conv to i33 @@ -375,9 +363,8 @@ define i33 @float_fptosi_i64_i33_noundef(float noundef %x) { ; CHECK-LABEL: @float_fptosi_i64_i33_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i33 -; CHECK-NEXT: ret i33 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i33 +; CHECK-NEXT: ret i33 [[CONV]] ; %conv = fptosi float %x to i64 %conv.1 = trunc i64 %conv to i33 @@ -386,9 +373,8 @@ define i64 @float_fptosi_i128_i64(float %x) { ; CHECK-LABEL: @float_fptosi_i128_i64( -; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i128 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i128 [[CONV]] to i64 -; CHECK-NEXT: ret i64 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %conv = fptosi float %x to i128 %conv.1 = trunc i128 %conv to i64 @@ -397,9 +383,8 @@ define i64 @float_fptosi_i128_i64_noundef(float noundef %x) { ; CHECK-LABEL: @float_fptosi_i128_i64_noundef( -; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i128 -; CHECK-NEXT: [[CONV_1:%.*]] = trunc i128 [[CONV]] to i64 -; CHECK-NEXT: ret i64 [[CONV_1]] +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 +; CHECK-NEXT: ret i64 [[CONV]] ; %conv = fptosi float %x to i128 %conv.1 = trunc i128 %conv to i64