280 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=aggressive-instcombine -mtriple aarch64 -S | FileCheck %s --check-prefixes=CHECK,CHECK-FP3; RUN: opt < %s -passes=aggressive-instcombine -mtriple aarch64 -mattr=+fullfp16 -S | FileCheck %s --check-prefixes=CHECK,CHECK-FP164 5define i64 @f32_i32(float %in) {6; CHECK-LABEL: @f32_i32(7; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[IN:%.*]])8; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i649; CHECK-NEXT: ret i64 [[TMP2]]10;11 %conv = fptosi float %in to i6412 %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)13 %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)14 ret i64 %max15}16 17define i64 @f32_i31(float %in) {18; CHECK-LABEL: @f32_i31(19; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i6420; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823)21; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824)22; CHECK-NEXT: ret i64 [[MAX]]23;24 %conv = fptosi float %in to i6425 %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823)26 %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824)27 ret i64 %max28}29 30define i32 @f32_i16(float %in) {31; CHECK-LABEL: @f32_i16(32; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i3233; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767)34; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768)35; CHECK-NEXT: ret i32 [[MAX]]36;37 %conv = fptosi float %in to i3238 %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767)39 %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768)40 ret i32 %max41}42 43define i32 @f32_i8(float %in) {44; CHECK-LABEL: @f32_i8(45; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i3246; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127)47; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128)48; CHECK-NEXT: ret i32 [[MAX]]49;50 %conv = fptosi float %in to i3251 %min = call i32 @llvm.smin.i32(i32 %conv, i32 127)52 %max = call i32 @llvm.smax.i32(i32 %min, i32 -128)53 ret i32 %max54}55 56define i64 @f64_i32(double %in) {57; CHECK-LABEL: @f64_i32(58; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f64(double [[IN:%.*]])59; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i6460; CHECK-NEXT: ret i64 [[TMP2]]61;62 %conv = fptosi double %in to i6463 %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)64 %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)65 ret i64 %max66}67 68define i64 @f64_i31(double %in) {69; CHECK-LABEL: @f64_i31(70; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i6471; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823)72; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824)73; CHECK-NEXT: ret i64 [[MAX]]74;75 %conv = fptosi double %in to i6476 %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823)77 %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824)78 ret i64 %max79}80 81define i32 @f64_i16(double %in) {82; CHECK-LABEL: @f64_i16(83; CHECK-NEXT: [[CONV:%.*]] = fptosi double [[IN:%.*]] to i3284; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767)85; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768)86; CHECK-NEXT: ret i32 [[MAX]]87;88 %conv = fptosi double %in to i3289 %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767)90 %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768)91 ret i32 %max92}93 94define i64 @f16_i32(half %in) {95; CHECK-LABEL: @f16_i32(96; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f16(half [[IN:%.*]])97; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i6498; CHECK-NEXT: ret i64 [[TMP2]]99;100 %conv = fptosi half %in to i64101 %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)102 %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)103 ret i64 %max104}105 106define i64 @f16_i31(half %in) {107; CHECK-LABEL: @f16_i31(108; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i64109; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 1073741823)110; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -1073741824)111; CHECK-NEXT: ret i64 [[MAX]]112;113 %conv = fptosi half %in to i64114 %min = call i64 @llvm.smin.i64(i64 %conv, i64 1073741823)115 %max = call i64 @llvm.smax.i64(i64 %min, i64 -1073741824)116 ret i64 %max117}118 119define i32 @f16_i16(half %in) {120; CHECK-LABEL: @f16_i16(121; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32122; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 32767)123; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -32768)124; CHECK-NEXT: ret i32 [[MAX]]125;126 %conv = fptosi half %in to i32127 %min = call i32 @llvm.smin.i32(i32 %conv, i32 32767)128 %max = call i32 @llvm.smax.i32(i32 %min, i32 -32768)129 ret i32 %max130}131 132define i32 @f16_i8(half %in) {133; CHECK-LABEL: @f16_i8(134; CHECK-NEXT: [[CONV:%.*]] = fptosi half [[IN:%.*]] to i32135; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[CONV]], i32 127)136; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 -128)137; CHECK-NEXT: ret i32 [[MAX]]138;139 %conv = fptosi half %in to i32140 %min = call i32 @llvm.smin.i32(i32 %conv, i32 127)141 %max = call i32 @llvm.smax.i32(i32 %min, i32 -128)142 ret i32 %max143}144 145define <2 x i64> @v2f32_i32(<2 x float> %in) {146; CHECK-LABEL: @v2f32_i32(147; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> [[IN:%.*]])148; CHECK-NEXT: [[TMP2:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>149; CHECK-NEXT: ret <2 x i64> [[TMP2]]150;151 %conv = fptosi <2 x float> %in to <2 x i64>152 %min = call <2 x i64> @llvm.smin.v2i64(<2 x i64> %conv, <2 x i64> <i64 2147483647, i64 2147483647>)153 %max = call <2 x i64> @llvm.smax.v2i64(<2 x i64> %min, <2 x i64> <i64 -2147483648, i64 -2147483648>)154 ret <2 x i64> %max155}156 157define <4 x i64> @v4f32_i32(<4 x float> %in) {158; CHECK-LABEL: @v4f32_i32(159; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> [[IN:%.*]])160; CHECK-NEXT: [[TMP2:%.*]] = sext <4 x i32> [[TMP1]] to <4 x i64>161; CHECK-NEXT: ret <4 x i64> [[TMP2]]162;163 %conv = fptosi <4 x float> %in to <4 x i64>164 %min = call <4 x i64> @llvm.smin.v4i64(<4 x i64> %conv, <4 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)165 %max = call <4 x i64> @llvm.smax.v4i64(<4 x i64> %min, <4 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)166 ret <4 x i64> %max167}168 169define <8 x i64> @v8f32_i32(<8 x float> %in) {170; CHECK-LABEL: @v8f32_i32(171; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> [[IN:%.*]])172; CHECK-NEXT: [[TMP2:%.*]] = sext <8 x i32> [[TMP1]] to <8 x i64>173; CHECK-NEXT: ret <8 x i64> [[TMP2]]174;175 %conv = fptosi <8 x float> %in to <8 x i64>176 %min = call <8 x i64> @llvm.smin.v8i64(<8 x i64> %conv, <8 x i64> <i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647, i64 2147483647>)177 %max = call <8 x i64> @llvm.smax.v8i64(<8 x i64> %min, <8 x i64> <i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648, i64 -2147483648>)178 ret <8 x i64> %max179}180 181define <4 x i32> @v4f16_i16(<4 x half> %in) {182; CHECK-LABEL: @v4f16_i16(183; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> [[IN:%.*]])184; CHECK-NEXT: [[TMP2:%.*]] = sext <4 x i16> [[TMP1]] to <4 x i32>185; CHECK-NEXT: ret <4 x i32> [[TMP2]]186;187 %conv = fptosi <4 x half> %in to <4 x i32>188 %min = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %conv, <4 x i32> <i32 32767, i32 32767, i32 32767, i32 32767>)189 %max = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %min, <4 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768>)190 ret <4 x i32> %max191}192 193define <8 x i32> @v8f16_i16(<8 x half> %in) {194; CHECK-LABEL: @v8f16_i16(195; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> [[IN:%.*]])196; CHECK-NEXT: [[TMP2:%.*]] = sext <8 x i16> [[TMP1]] to <8 x i32>197; CHECK-NEXT: ret <8 x i32> [[TMP2]]198;199 %conv = fptosi <8 x half> %in to <8 x i32>200 %min = call <8 x i32> @llvm.smin.v8i32(<8 x i32> %conv, <8 x i32> <i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767, i32 32767>)201 %max = call <8 x i32> @llvm.smax.v8i32(<8 x i32> %min, <8 x i32> <i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768, i32 -32768>)202 ret <8 x i32> %max203}204 205 206define i64 @f32_i32_extrause1(float %in) {207; CHECK-LABEL: @f32_i32_extrause1(208; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64209; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647)210; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648)211; CHECK-NEXT: call void @use(i64 [[MIN]])212; CHECK-NEXT: ret i64 [[MAX]]213;214 %conv = fptosi float %in to i64215 %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)216 %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)217 call void @use(i64 %min)218 ret i64 %max219}220 221define i64 @f32_i32_extrause2(float %in) {222; CHECK-LABEL: @f32_i32_extrause2(223; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64224; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 2147483647)225; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 -2147483648)226; CHECK-NEXT: call void @use(i64 [[CONV]])227; CHECK-NEXT: ret i64 [[MAX]]228;229 %conv = fptosi float %in to i64230 %min = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647)231 %max = call i64 @llvm.smax.i64(i64 %min, i64 -2147483648)232 call void @use(i64 %conv)233 ret i64 %max234}235 236define i64 @f32_i32_invertedconsts(float %in) {237; CHECK-LABEL: @f32_i32_invertedconsts(238; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[IN:%.*]] to i64239; CHECK-NEXT: [[MIN:%.*]] = call i64 @llvm.smin.i64(i64 [[CONV]], i64 -2147483648)240; CHECK-NEXT: [[MAX:%.*]] = call i64 @llvm.smax.i64(i64 [[MIN]], i64 2147483647)241; CHECK-NEXT: ret i64 [[MAX]]242;243 %conv = fptosi float %in to i64244 %min = call i64 @llvm.smin.i64(i64 %conv, i64 -2147483648)245 %max = call i64 @llvm.smax.i64(i64 %min, i64 2147483647)246 ret i64 %max247}248 249define i64 @f32_i32_maxmin(float %in) {250; CHECK-LABEL: @f32_i32_maxmin(251; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[IN:%.*]])252; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64253; CHECK-NEXT: ret i64 [[TMP2]]254;255 %conv = fptosi float %in to i64256 %max = call i64 @llvm.smax.i64(i64 %conv, i64 -2147483648)257 %min = call i64 @llvm.smin.i64(i64 %max, i64 2147483647)258 ret i64 %min259}260 261 262declare void @use(i64)263declare i64 @llvm.smin.i64(i64, i64)264declare i64 @llvm.smax.i64(i64, i64)265declare i32 @llvm.smin.i32(i32, i32)266declare i32 @llvm.smax.i32(i32, i32)267declare <2 x i64> @llvm.smin.v2i64(<2 x i64>, <2 x i64>)268declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)269declare <4 x i64> @llvm.smin.v4i64(<4 x i64>, <4 x i64>)270declare <4 x i64> @llvm.smax.v4i64(<4 x i64>, <4 x i64>)271declare <8 x i64> @llvm.smin.v8i64(<8 x i64>, <8 x i64>)272declare <8 x i64> @llvm.smax.v8i64(<8 x i64>, <8 x i64>)273declare <4 x i32> @llvm.smin.v4i32(<4 x i32>, <4 x i32>)274declare <4 x i32> @llvm.smax.v4i32(<4 x i32>, <4 x i32>)275declare <8 x i32> @llvm.smin.v8i32(<8 x i32>, <8 x i32>)276declare <8 x i32> @llvm.smax.v8i32(<8 x i32>, <8 x i32>)277;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:278; CHECK-FP: {{.*}}279; CHECK-FP16: {{.*}}280