diff --git a/llvm/test/Transforms/AggressiveInstCombine/AArch64/fptosisat.ll b/llvm/test/Transforms/AggressiveInstCombine/AArch64/fptosisat.ll new file mode 100644 index 0000000000000..fb616f4ebb0f1 --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/AArch64/fptosisat.ll @@ -0,0 +1,285 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=aggressive-instcombine -mtriple aarch64-none-eabi -S | FileCheck %s +; RUN: opt < %s -passes=aggressive-instcombine -mtriple aarch64-none-eabi -mattr=+fullfp16 -S | FileCheck %s + +define i64 @f32_i32(float %in) { +; CHECK-LABEL: @f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f32_i31(float %in) { +; CHECK-LABEL: @f32_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f32_i16(float %in) { +; CHECK-LABEL: @f32_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi float %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i32 @f32_i8(float %in) { +; CHECK-LABEL: @f32_i8( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi float %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 127) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -128) + ret i32 %max +} + +define i64 @f64_i32(double %in) { +; CHECK-LABEL: @f64_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi double %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f64_i31(double %in) { +; CHECK-LABEL: @f64_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi double %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f64_i16(double %in) { +; CHECK-LABEL: @f64_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi double %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i64 @f16_i32(half %in) { +; CHECK-LABEL: @f16_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi half %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f16_i31(half %in) { +; CHECK-LABEL: @f16_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi half %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f16_i16(half %in) { +; CHECK-LABEL: @f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi half %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i32 @f16_i8(half %in) { +; CHECK-LABEL: @f16_i8( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi half %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 127) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -128) + ret i32 %max +} + +define <2 x i64> @v2f32_i32(<2 x float> %in) { +; CHECK-LABEL: @v2f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <2 x float> [[IN:%.*]] to <2 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i64> @llvm.smin.v2i64(<2 x i64> [[CONV]], <2 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i64> @llvm.smax.v2i64(<2 x i64> [[MIN]], <2 x i64> ) +; CHECK-NEXT: ret <2 x i64> [[MAX]] +; + %conv = fptosi <2 x float> %in to <2 x i64> + %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %conv, <2 x i64> ) + %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> ) + ret <2 x i64> %max +} + +define <4 x i64> @v4f32_i32(<4 x float> %in) { +; CHECK-LABEL: @v4f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x float> [[IN:%.*]] to <4 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[CONV]], <4 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <4 x i64> @llvm.smax.v4i64(<4 x i64> [[MIN]], <4 x i64> ) +; CHECK-NEXT: ret <4 x i64> [[MAX]] +; + %conv = fptosi <4 x float> %in to <4 x i64> + %min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> ) + %max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %min, <4 x i64> ) + ret <4 x i64> %max +} + +define <8 x i64> @v8f32_i32(<8 x float> %in) { +; CHECK-LABEL: @v8f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <8 x float> [[IN:%.*]] to <8 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <8 x i64> @llvm.smin.v8i64(<8 x i64> [[CONV]], <8 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <8 x i64> @llvm.smax.v8i64(<8 x i64> [[MIN]], <8 x i64> ) +; CHECK-NEXT: ret <8 x i64> [[MAX]] +; + %conv = fptosi <8 x float> %in to <8 x i64> + %min = call <8 x i64> @llvm.smin.v8i64(<8 x i64> %conv, <8 x i64> ) + %max = call <8 x i64> @llvm.smax.v8i64(<8 x i64> %min, <8 x i64> ) + ret <8 x i64> %max +} + +define <4 x i32> @v4f16_i16(<4 x half> %in) { +; CHECK-LABEL: @v4f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x half> [[IN:%.*]] to <4 x i32> +; CHECK-NEXT: [[MIN:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[CONV]], <4 x i32> ) +; CHECK-NEXT: [[MAX:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[MIN]], <4 x i32> ) +; CHECK-NEXT: ret <4 x i32> [[MAX]] +; + %conv = fptosi <4 x half> %in to <4 x i32> + %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %conv, <4 x i32> ) + %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> ) + ret <4 x i32> %max +} + +define <8 x i32> @v8f16_i16(<8 x half> %in) { +; CHECK-LABEL: @v8f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <8 x half> [[IN:%.*]] to <8 x i32> +; CHECK-NEXT: [[MIN:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[CONV]], <8 x i32> ) +; CHECK-NEXT: [[MAX:%.*]] = call <8 x i32> @llvm.smax.v8i32(<8 x i32> [[MIN]], <8 x i32> ) +; CHECK-NEXT: ret <8 x i32> [[MAX]] +; + %conv = fptosi <8 x half> %in to <8 x i32> + %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> ) + %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> ) + ret <8 x i32> %max +} + + +define i64 @f32_i32_extrause1(float %in) { +; CHECK-LABEL: @f32_i32_extrause1( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: call void @use(i64 [[MIN]]) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + call void @use(i64 %min) + ret i64 %max +} + +define i64 @f32_i32_extrause2(float %in) { +; CHECK-LABEL: @f32_i32_extrause2( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: call void @use(i64 [[CONV]]) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + call void @use(i64 %conv) + ret i64 %max +} + +define i64 @f32_i32_invertedconsts(float %in) { +; CHECK-LABEL: @f32_i32_invertedconsts( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 -2147483648) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 2147483647) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 -2147483648) + %max = call i64 @llvm.smax.i64(i64 %min, i64 2147483647) + ret i64 %max +} + +define i64 @f32_i32_maxmin(float %in) { +; CHECK-LABEL: @f32_i32_maxmin( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[CONV]], i64 -2147483648) +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[MAX]], i64 2147483647) +; CHECK-NEXT: ret i64 [[MIN]] +; + %conv = fptosi float %in to i64 + %max = call i64 @llvm.smax.i64(i64 %conv, i64 -2147483648) + %min = call i64 @llvm.smin.i64(i64 %max, i64 2147483647) + ret i64 %min +} + + +declare void @use(i64) +declare i64 @llvm.smin.i64(i64, i64) +declare i64 @llvm.smax.i64(i64, i64) +declare i32 @llvm.smin.i32(i32, i32) +declare i32 @llvm.smax.i32(i32, i32) +declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>) +declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>) +declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>) +declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>) +declare <8 x i64> @llvm.smin.v8i64(<8 x i64>, <8 x i64>) +declare <8 x i64> @llvm.smax.v8i64(<8 x i64>, <8 x i64>) +declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>) +declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>) +declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>) diff --git a/llvm/test/Transforms/AggressiveInstCombine/AArch64/lit.local.cfg b/llvm/test/Transforms/AggressiveInstCombine/AArch64/lit.local.cfg new file mode 100644 index 0000000000000..7184443994b69 --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/AArch64/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'AArch64' in config.root.targets: + config.unsupported = True diff --git a/llvm/test/Transforms/AggressiveInstCombine/ARM/fptosisat.ll b/llvm/test/Transforms/AggressiveInstCombine/ARM/fptosisat.ll new file mode 100644 index 0000000000000..6d2897ba8050b --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/ARM/fptosisat.ll @@ -0,0 +1,228 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=aggressive-instcombine -mtriple thumbv8.1m.main-none-eabi -S | FileCheck %s +; RUN: opt < %s -passes=aggressive-instcombine -mtriple thumbv8.1m.main-none-eabi -mattr=+mve.fp -S | FileCheck %s +; RUN: opt < %s -passes=aggressive-instcombine -mtriple thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -S | FileCheck %s + +define i64 @f32_i32(float %in) { +; CHECK-LABEL: @f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f32_i31(float %in) { +; CHECK-LABEL: @f32_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f32_i16(float %in) { +; CHECK-LABEL: @f32_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi float %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i32 @f32_i8(float %in) { +; CHECK-LABEL: @f32_i8( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi float %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 127) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -128) + ret i32 %max +} + +define i64 @f64_i32(double %in) { +; CHECK-LABEL: @f64_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi double %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f64_i31(double %in) { +; CHECK-LABEL: @f64_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi double %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f64_i16(double %in) { +; CHECK-LABEL: @f64_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi double %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i64 @f16_i32(half %in) { +; CHECK-LABEL: @f16_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi half %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f16_i31(half %in) { +; CHECK-LABEL: @f16_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi half %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f16_i16(half %in) { +; CHECK-LABEL: @f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi half %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i32 @f16_i8(half %in) { +; CHECK-LABEL: @f16_i8( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi half %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 127) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -128) + ret i32 %max +} + +define <2 x i64> @v2f32_i32(<2 x float> %in) { +; CHECK-LABEL: @v2f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <2 x float> [[IN:%.*]] to <2 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <2 x i64> @llvm.smin.v2i64(<2 x i64> [[CONV]], <2 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <2 x i64> @llvm.smax.v2i64(<2 x i64> [[MIN]], <2 x i64> ) +; CHECK-NEXT: ret <2 x i64> [[MAX]] +; + %conv = fptosi <2 x float> %in to <2 x i64> + %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %conv, <2 x i64> ) + %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> ) + ret <2 x i64> %max +} + +define <4 x i64> @v4f32_i32(<4 x float> %in) { +; CHECK-LABEL: @v4f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x float> [[IN:%.*]] to <4 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[CONV]], <4 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <4 x i64> @llvm.smax.v4i64(<4 x i64> [[MIN]], <4 x i64> ) +; CHECK-NEXT: ret <4 x i64> [[MAX]] +; + %conv = fptosi <4 x float> %in to <4 x i64> + %min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> ) + %max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %min, <4 x i64> ) + ret <4 x i64> %max +} + +define <8 x i64> @v8f32_i32(<8 x float> %in) { +; CHECK-LABEL: @v8f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <8 x float> [[IN:%.*]] to <8 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <8 x i64> @llvm.smin.v8i64(<8 x i64> [[CONV]], <8 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <8 x i64> @llvm.smax.v8i64(<8 x i64> [[MIN]], <8 x i64> ) +; CHECK-NEXT: ret <8 x i64> [[MAX]] +; + %conv = fptosi <8 x float> %in to <8 x i64> + %min = call <8 x i64> @llvm.smin.v8i64(<8 x i64> %conv, <8 x i64> ) + %max = call <8 x i64> @llvm.smax.v8i64(<8 x i64> %min, <8 x i64> ) + ret <8 x i64> %max +} + +define <4 x i32> @v4f16_i16(<4 x half> %in) { +; CHECK-LABEL: @v4f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x half> [[IN:%.*]] to <4 x i32> +; CHECK-NEXT: [[MIN:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[CONV]], <4 x i32> ) +; CHECK-NEXT: [[MAX:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[MIN]], <4 x i32> ) +; CHECK-NEXT: ret <4 x i32> [[MAX]] +; + %conv = fptosi <4 x half> %in to <4 x i32> + %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %conv, <4 x i32> ) + %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> ) + ret <4 x i32> %max +} + +define <8 x i32> @v8f16_i16(<8 x half> %in) { +; CHECK-LABEL: @v8f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <8 x half> [[IN:%.*]] to <8 x i32> +; CHECK-NEXT: [[MIN:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[CONV]], <8 x i32> ) +; CHECK-NEXT: [[MAX:%.*]] = call <8 x i32> @llvm.smax.v8i32(<8 x i32> [[MIN]], <8 x i32> ) +; CHECK-NEXT: ret <8 x i32> [[MAX]] +; + %conv = fptosi <8 x half> %in to <8 x i32> + %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> ) + %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> ) + ret <8 x i32> %max +} + + +declare i64 @llvm.smin.i64(i64, i64) +declare i64 @llvm.smax.i64(i64, i64) +declare i32 @llvm.smin.i32(i32, i32) +declare i32 @llvm.smax.i32(i32, i32) +declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>) +declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>) +declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>) +declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>) +declare <8 x i64> @llvm.smin.v8i64(<8 x i64>, <8 x i64>) +declare <8 x i64> @llvm.smax.v8i64(<8 x i64>, <8 x i64>) +declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>) +declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>) +declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>) diff --git a/llvm/test/Transforms/AggressiveInstCombine/ARM/lit.local.cfg b/llvm/test/Transforms/AggressiveInstCombine/ARM/lit.local.cfg new file mode 100644 index 0000000000000..236e1d3441665 --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/ARM/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'ARM' in config.root.targets: + config.unsupported = True diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/fptosisat.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/fptosisat.ll new file mode 100644 index 0000000000000..5f13beacb6bbb --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/X86/fptosisat.ll @@ -0,0 +1,187 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=aggressive-instcombine -mtriple x86_64-none-eabi -mattr=avx2 -S | FileCheck %s + +define i64 @f32_i32(float %in) { +; CHECK-LABEL: @f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f32_i31(float %in) { +; CHECK-LABEL: @f32_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi float %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f32_i16(float %in) { +; CHECK-LABEL: @f32_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi float %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i32 @f32_i8(float %in) { +; CHECK-LABEL: @f32_i8( +; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi float %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 127) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -128) + ret i32 %max +} + +define i64 @f64_i32(double %in) { +; CHECK-LABEL: @f64_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi double %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f64_i31(double %in) { +; CHECK-LABEL: @f64_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi double %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f64_i16(double %in) { +; CHECK-LABEL: @f64_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi double %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i64 @f16_i32(half %in) { +; CHECK-LABEL: @f16_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi half %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648) + ret i64 %max +} + +define i64 @f16_i31(half %in) { +; CHECK-LABEL: @f16_i31( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64 +; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823) +; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824) +; CHECK-NEXT: ret i64 [[MAX]] +; + %conv = fptosi half %in to i64 + %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823) + %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824) + ret i64 %max +} + +define i32 @f16_i16(half %in) { +; CHECK-LABEL: @f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi half %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768) + ret i32 %max +} + +define i32 @f16_i8(half %in) { +; CHECK-LABEL: @f16_i8( +; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32 +; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127) +; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128) +; CHECK-NEXT: ret i32 [[MAX]] +; + %conv = fptosi half %in to i32 + %min = call i32 @llvm.smin.i32(i32 %conv, i32 127) + %max = call i32 @llvm.smax.i32(i32 %min, i32 -128) + ret i32 %max +} + +define <4 x i64> @v4f32_i32(<4 x float> %in) { +; CHECK-LABEL: @v4f32_i32( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <4 x float> [[IN:%.*]] to <4 x i64> +; CHECK-NEXT: [[MIN:%.*]] = call <4 x i64> @llvm.smin.v4i64(<4 x i64> [[CONV]], <4 x i64> ) +; CHECK-NEXT: [[MAX:%.*]] = call <4 x i64> @llvm.smax.v4i64(<4 x i64> [[MIN]], <4 x i64> ) +; CHECK-NEXT: ret <4 x i64> [[MAX]] +; + %conv = fptosi <4 x float> %in to <4 x i64> + %min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> ) + %max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %min, <4 x i64> ) + ret <4 x i64> %max +} + +define <8 x i32> @v8f16_i16(<8 x half> %in) { +; CHECK-LABEL: @v8f16_i16( +; CHECK-NEXT: [[CONV:%.*]] = fptosi <8 x half> [[IN:%.*]] to <8 x i32> +; CHECK-NEXT: [[MIN:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[CONV]], <8 x i32> ) +; CHECK-NEXT: [[MAX:%.*]] = call <8 x i32> @llvm.smax.v8i32(<8 x i32> [[MIN]], <8 x i32> ) +; CHECK-NEXT: ret <8 x i32> [[MAX]] +; + %conv = fptosi <8 x half> %in to <8 x i32> + %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> ) + %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> ) + ret <8 x i32> %max +} + + +declare i64 @llvm.smin.i64(i64, i64) +declare i64 @llvm.smax.i64(i64, i64) +declare i32 @llvm.smin.i32(i32, i32) +declare i32 @llvm.smax.i32(i32, i32) +declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>) +declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>) +declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>) +declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>) +declare <8 x i64> @llvm.smin.v8i64(<8 x i64>, <8 x i64>) +declare <8 x i64> @llvm.smax.v8i64(<8 x i64>, <8 x i64>) +declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>) +declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>) +declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>) +declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>) diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/lit.local.cfg b/llvm/test/Transforms/AggressiveInstCombine/X86/lit.local.cfg new file mode 100644 index 0000000000000..c8625f4d9d248 --- /dev/null +++ b/llvm/test/Transforms/AggressiveInstCombine/X86/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'X86' in config.root.targets: + config.unsupported = True