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,17 @@ return false; return true; } + case Instruction::FPToUI: + if (I->getOperand(0)->getType()->getScalarType()->isHalfTy()) + return Ty->getScalarSizeInBits() >= 16; + break; + case Instruction::FPToSI: + // TODO: For FPToSI, the minimum trunc type is i17 but we only handle + // simple types while evaluating truncations. + if (isGuaranteedNotToBeUndefOrPoison(I->getOperand(0))) + if (I->getOperand(0)->getType()->getScalarType()->isHalfTy()) + return Ty->getScalarSizeInBits() >= 32; + break; default: // TODO: Can handle more cases here. break; Index: llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll @@ -0,0 +1,151 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s + +define i15 @half_fptoui_i32_i15_noundef(half noundef %x) { +; CHECK-LABEL: @half_fptoui_i32_i15_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptoui half [[X:%.*]] to i32 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i32 [[CONV]] to i15 +; CHECK-NEXT: ret i15 [[CONV_1]] +; + %conv = fptoui half %x to i32 + %conv.1 = trunc i32 %conv to i15 + ret i15 %conv.1 +} + +define i16 @half_fptoui_i32_i16_noundef(half noundef %x) { +; CHECK-LABEL: @half_fptoui_i32_i16_noundef( +; 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 + ret i16 %conv.1 +} + +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 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> + ret <4 x i16> %conv.1 +} + +define i16 @half_fptoui_i32_i16(half %x) { +; CHECK-LABEL: @half_fptoui_i32_i16( +; 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 + ret i16 %conv.1 +} + +define i16 @half_fptosi_i32_i16_noundef(half noundef %x) { +; CHECK-LABEL: @half_fptosi_i32_i16_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[X:%.*]] to i32 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i32 [[CONV]] to i16 +; CHECK-NEXT: ret i16 [[CONV_1]] +; + %conv = fptosi half %x to i32 + %conv.1 = trunc i32 %conv to i16 + ret i16 %conv.1 +} + +define i17 @half_fptosi_i32_i17_noundef(half noundef %x) { +; CHECK-LABEL: @half_fptosi_i32_i17_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[X:%.*]] to i32 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i32 [[CONV]] to i17 +; CHECK-NEXT: ret i17 [[CONV_1]] +; + %conv = fptosi half %x to i32 + %conv.1 = trunc i32 %conv to i17 + ret i17 %conv.1 +} + +define i17 @half_fptosi_i32_i17(half %x) { +; CHECK-LABEL: @half_fptosi_i32_i17( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[X:%.*]] to i32 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i32 [[CONV]] to i17 +; CHECK-NEXT: ret i17 [[CONV_1]] +; + %conv = fptosi half %x to i32 + %conv.1 = trunc i32 %conv to i17 + ret i17 %conv.1 +} + +define i32 @half_fptosi_i64_i32_noundef(half noundef %x) { +; CHECK-LABEL: @half_fptosi_i64_i32_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[X:%.*]] to i32 +; CHECK-NEXT: ret i32 [[CONV]] +; + %conv = fptosi half %x to i64 + %conv.1 = trunc i64 %conv to i32 + ret i32 %conv.1 +} + +define <4 x i32> @half_fptosi_4xi64_4xi32_noundef(<4 x half> noundef %x) { +; CHECK-LABEL: @half_fptosi_4xi64_4xi32_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i32> +; CHECK-NEXT: ret <4 x i32> [[CONV]] +; + %conv = fptoui <4 x half> %x to <4 x i64> + %conv.1 = trunc <4 x i64> %conv to <4 x i32> + ret <4 x i32> %conv.1 +} + +define i32 @half_fptosi_i64_i32(half %x) { +; CHECK-LABEL: @half_fptosi_i64_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[X:%.*]] to i64 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i32 +; CHECK-NEXT: ret i32 [[CONV_1]] +; + %conv = fptosi half %x to i64 + %conv.1 = trunc i64 %conv to i32 + ret i32 %conv.1 +} + +define i32 @float_fptoui_i64_i32_noundef(float noundef %x) { +; CHECK-LABEL: @float_fptoui_i64_i32_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptoui float [[X:%.*]] to i64 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i32 +; CHECK-NEXT: ret i32 [[CONV_1]] +; + %conv = fptoui float %x to i64 + %conv.1 = trunc i64 %conv to i32 + ret i32 %conv.1 +} + +define i32 @float_fptosi_i64_i32_noundef(float noundef %x) { +; CHECK-LABEL: @float_fptosi_i64_i32_noundef( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[X:%.*]] to i64 +; CHECK-NEXT: [[CONV_1:%.*]] = trunc i64 [[CONV]] to i32 +; CHECK-NEXT: ret i32 [[CONV_1]] +; + %conv = fptosi float %x to i64 + %conv.1 = trunc i64 %conv to i32 + ret i32 %conv.1 +} + +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]] +; + %conv = fptoui float %x to i128 + %conv.1 = trunc i128 %conv to i64 + ret i64 %conv.1 +} + +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]] +; + %conv = fptosi float %x to i128 + %conv.1 = trunc i128 %conv to i64 + ret i64 %conv.1 +}