368 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; smax(smin(X, MinC), MaxC) -> smin(smax(X, MaxC), MinC)5; umax(umin(X, MinC), MaxC) -> umin(smax(X, MaxC), MinC)6 7 8define i16 @smax_smin(i16 %x) {9; CHECK-LABEL: define i16 @smax_smin(10; CHECK-SAME: i16 [[X:%.*]]) {11; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -1)12; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 255)13; CHECK-NEXT: ret i16 [[MAX]]14;15 %min = call i16 @llvm.smin.i16(i16 %x, i16 255)16 %max = call i16 @llvm.smax.i16(i16 %min, i16 -1)17 ret i16 %max18}19 20define i16 @umax_umin(i16 %x) {21; CHECK-LABEL: define i16 @umax_umin(22; CHECK-SAME: i16 [[X:%.*]]) {23; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 63)24; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)25; CHECK-NEXT: ret i16 [[MAX]]26;27 %min = call i16 @llvm.umin.i16(i16 %x, i16 255)28 %max = call i16 @llvm.umax.i16(i16 %min, i16 63)29 ret i16 %max30}31 32define i16 @smax_smin_commute0(i16 %x) {33; CHECK-LABEL: define i16 @smax_smin_commute0(34; CHECK-SAME: i16 [[X:%.*]]) {35; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)36; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)37; CHECK-NEXT: ret i16 [[MAX]]38;39 %min = call i16 @llvm.smin.i16(i16 %x, i16 127)40 %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)41 ret i16 %max42}43 44define i16 @umax_umin_commute0(i16 %x) {45; CHECK-LABEL: define i16 @umax_umin_commute0(46; CHECK-SAME: i16 [[X:%.*]]) {47; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)48; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)49; CHECK-NEXT: ret i16 [[MAX]]50;51 %min = call i16 @llvm.umin.i16(i16 %x, i16 255)52 %max = call i16 @llvm.umax.i16(i16 %min, i16 127)53 ret i16 %max54}55 56define i16 @smax_smin_commute1(i16 %x) {57; CHECK-LABEL: define i16 @smax_smin_commute1(58; CHECK-SAME: i16 [[X:%.*]]) {59; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)60; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)61; CHECK-NEXT: ret i16 [[MAX]]62;63 %min = call i16 @llvm.smin.i16(i16 127, i16 %x)64 %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)65 ret i16 %max66}67 68define i16 @umax_umin_commute1(i16 %x) {69; CHECK-LABEL: define i16 @umax_umin_commute1(70; CHECK-SAME: i16 [[X:%.*]]) {71; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)72; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)73; CHECK-NEXT: ret i16 [[MAX]]74;75 %min = call i16 @llvm.umin.i16(i16 255, i16 %x)76 %max = call i16 @llvm.umax.i16(i16 %min, i16 127)77 ret i16 %max78}79 80define i16 @smax_smin_commute2(i16 %x) {81; CHECK-LABEL: define i16 @smax_smin_commute2(82; CHECK-SAME: i16 [[X:%.*]]) {83; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)84; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)85; CHECK-NEXT: ret i16 [[MAX]]86;87 %min = call i16 @llvm.smin.i16(i16 %x, i16 127)88 %max = call i16 @llvm.smax.i16(i16 -128, i16 %min)89 ret i16 %max90}91 92define i16 @umax_umin_commute2(i16 %x) {93; CHECK-LABEL: define i16 @umax_umin_commute2(94; CHECK-SAME: i16 [[X:%.*]]) {95; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)96; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)97; CHECK-NEXT: ret i16 [[MAX]]98;99 %min = call i16 @llvm.umin.i16(i16 %x, i16 255)100 %max = call i16 @llvm.umax.i16(i16 127, i16 %min)101 ret i16 %max102}103 104define i16 @smax_smin_commute3(i16 %x) {105; CHECK-LABEL: define i16 @smax_smin_commute3(106; CHECK-SAME: i16 [[X:%.*]]) {107; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)108; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)109; CHECK-NEXT: ret i16 [[MAX]]110;111 %min = call i16 @llvm.smin.i16(i16 %x, i16 127)112 %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)113 ret i16 %max114}115 116define i16 @umax_umin_commute3(i16 %x) {117; CHECK-LABEL: define i16 @umax_umin_commute3(118; CHECK-SAME: i16 [[X:%.*]]) {119; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)120; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umin.i16(i16 [[TMP1]], i16 255)121; CHECK-NEXT: ret i16 [[MAX]]122;123 %min = call i16 @llvm.umin.i16(i16 %x, i16 255)124 %max = call i16 @llvm.umax.i16(i16 %min, i16 127)125 ret i16 %max126}127 128define <2 x i16> @smax_smin_v2i16(<2 x i16> %x) {129; CHECK-LABEL: define <2 x i16> @smax_smin_v2i16(130; CHECK-SAME: <2 x i16> [[X:%.*]]) {131; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 -128))132; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[TMP1]], <2 x i16> splat (i16 127))133; CHECK-NEXT: ret <2 x i16> [[MAX]]134;135 %min = call <2 x i16> @llvm.smin.v2i16(<2 x i16> %x, <2 x i16> splat (i16 127))136 %max = call <2 x i16> @llvm.smax.v2i16(<2 x i16> %min, <2 x i16> splat (i16 -128))137 ret <2 x i16> %max138}139 140define <2 x i16> @umax_umin_v2i16(<2 x i16> %x) {141; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16(142; CHECK-SAME: <2 x i16> [[X:%.*]]) {143; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[X]], <2 x i16> splat (i16 127))144; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[TMP1]], <2 x i16> splat (i16 255))145; CHECK-NEXT: ret <2 x i16> [[MAX]]146;147 %min = call <2 x i16> @llvm.umin.v2i16(<2 x i16> %x, <2 x i16> splat (i16 255))148 %max = call <2 x i16> @llvm.umax.v2i16(<2 x i16> %min, <2 x i16> splat (i16 127))149 ret <2 x i16> %max150}151 152define <2 x i8> @smax_smin_v2i16_nonsplat_1(<2 x i8> %a) {153; CHECK-LABEL: define <2 x i8> @smax_smin_v2i16_nonsplat_1(154; CHECK-SAME: <2 x i8> [[A:%.*]]) {155; CHECK-NEXT: [[MIN:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[A]], <2 x i8> <i8 20, i8 10>)156; CHECK-NEXT: [[MAX:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[MIN]], <2 x i8> <i8 10, i8 0>)157; CHECK-NEXT: ret <2 x i8> [[MAX]]158;159 %min = call <2 x i8> @llvm.smin(<2 x i8> %a, <2 x i8> <i8 20, i8 10>)160 %max = call <2 x i8> @llvm.smax(<2 x i8> %min, <2 x i8> <i8 10, i8 0>)161 ret <2 x i8> %max162}163 164define <2 x i16> @umax_umin_v2i16_nonsplat_1(<2 x i16> %a) {165; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16_nonsplat_1(166; CHECK-SAME: <2 x i16> [[A:%.*]]) {167; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[A]], <2 x i16> <i16 20, i16 10>)168; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[MIN]], <2 x i16> <i16 10, i16 1>)169; CHECK-NEXT: ret <2 x i16> [[MAX]]170;171 %min = call <2 x i16> @llvm.umin(<2 x i16> %a, <2 x i16> <i16 20, i16 10>)172 %max = call <2 x i16> @llvm.umax(<2 x i16> %min, <2 x i16> <i16 10, i16 1>)173 ret <2 x i16> %max174}175 176define <2 x i8> @smax_smin_v2i16_nonsplat_2(<2 x i8> %a) {177; CHECK-LABEL: define <2 x i8> @smax_smin_v2i16_nonsplat_2(178; CHECK-SAME: <2 x i8> [[A:%.*]]) {179; CHECK-NEXT: [[MIN:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[A]], <2 x i8> <i8 0, i8 10>)180; CHECK-NEXT: [[MAX:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[MIN]], <2 x i8> <i8 10, i8 0>)181; CHECK-NEXT: ret <2 x i8> [[MAX]]182;183 %min = call <2 x i8> @llvm.smin(<2 x i8> %a, <2 x i8> <i8 0, i8 10>)184 %max = call <2 x i8> @llvm.smax(<2 x i8> %min, <2 x i8> <i8 10, i8 0>)185 ret <2 x i8> %max186}187 188define <2 x i16> @umax_umin_v2i16_nonsplat_2(<2 x i16> %a) {189; CHECK-LABEL: define <2 x i16> @umax_umin_v2i16_nonsplat_2(190; CHECK-SAME: <2 x i16> [[A:%.*]]) {191; CHECK-NEXT: [[MIN:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[A]], <2 x i16> <i16 1, i16 10>)192; CHECK-NEXT: [[MAX:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[MIN]], <2 x i16> <i16 10, i16 1>)193; CHECK-NEXT: ret <2 x i16> [[MAX]]194;195 %min = call <2 x i16> @llvm.umin(<2 x i16> %a, <2 x i16> <i16 1, i16 10>)196 %max = call <2 x i16> @llvm.umax(<2 x i16> %min, <2 x i16> <i16 10, i16 1>)197 ret <2 x i16> %max198}199 200declare void @use(i16)201 202define i16 @smax_smin_used(i16 %x) {203; CHECK-LABEL: define i16 @smax_smin_used(204; CHECK-SAME: i16 [[X:%.*]]) {205; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 127)206; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 -128)207; CHECK-NEXT: call void @use(i16 [[MIN]])208; CHECK-NEXT: ret i16 [[MAX]]209;210 %min = call i16 @llvm.smin.i16(i16 %x, i16 127)211 %max = call i16 @llvm.smax.i16(i16 %min, i16 -128)212 call void @use(i16 %min)213 ret i16 %max214}215 216define i16 @umax_umin_used(i16 %x) {217; CHECK-LABEL: define i16 @umax_umin_used(218; CHECK-SAME: i16 [[X:%.*]]) {219; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 255)220; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 127)221; CHECK-NEXT: call void @use(i16 [[MIN]])222; CHECK-NEXT: ret i16 [[MAX]]223;224 %min = call i16 @llvm.umin.i16(i16 %x, i16 255)225 %max = call i16 @llvm.umax.i16(i16 %min, i16 127)226 call void @use(i16 %min)227 ret i16 %max228}229 230 231define i16 @smax_smin_i16_limits(i16 %x) {232; CHECK-LABEL: define i16 @smax_smin_i16_limits(233; CHECK-SAME: i16 [[X:%.*]]) {234; CHECK-NEXT: ret i16 [[X]]235;236 %min = call i16 @llvm.smin.i16(i16 %x, i16 32767)237 %max = call i16 @llvm.smax.i16(i16 %min, i16 -32768)238 ret i16 %max239}240 241define i16 @umax_umin_i16_limits(i16 %x) {242; CHECK-LABEL: define i16 @umax_umin_i16_limits(243; CHECK-SAME: i16 [[X:%.*]]) {244; CHECK-NEXT: ret i16 [[X]]245;246 %min = call i16 @llvm.umin.i16(i16 %x, i16 65535)247 %max = call i16 @llvm.umax.i16(i16 %min, i16 0)248 ret i16 %max249}250 251define i16 @min_smax_smin_nested(i16 %x) {252; CHECK-LABEL: define i16 @min_smax_smin_nested(253; CHECK-SAME: i16 [[X:%.*]]) {254; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)255; CHECK-NEXT: [[MIN2:%.*]] = call i16 @llvm.smin.i16(i16 [[TMP1]], i16 127)256; CHECK-NEXT: ret i16 [[MIN2]]257;258 %min1 = call i16 @llvm.smin.i16(i16 %x, i16 255)259 %max = call i16 @llvm.smax.i16(i16 %min1, i16 -128)260 %min2 = call i16 @llvm.smin.i16(i16 %max, i16 127)261 ret i16 %min2262}263 264define i16 @umax_umin_nested(i16 %x) {265; CHECK-LABEL: define i16 @umax_umin_nested(266; CHECK-SAME: i16 [[X:%.*]]) {267; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 63)268; CHECK-NEXT: [[MIN2:%.*]] = call i16 @llvm.umin.i16(i16 [[MAX]], i16 127)269; CHECK-NEXT: ret i16 [[MIN2]]270;271 %min1 = call i16 @llvm.umin.i16(i16 %x, i16 255)272 %max = call i16 @llvm.umax.i16(i16 %min1, i16 63)273 %min2 = call i16 @llvm.umin.i16(i16 %max, i16 127)274 ret i16 %min2275}276 277define i16 @smax_smin_cmax_sgt_cmin(i16 %x) {278; CHECK-LABEL: define i16 @smax_smin_cmax_sgt_cmin(279; CHECK-SAME: i16 [[X:%.*]]) {280; CHECK-NEXT: ret i16 127281;282 %min = call i16 @llvm.smin.i16(i16 %x, i16 126)283 %max = call i16 @llvm.smax.i16(i16 %min, i16 127)284 ret i16 %max285}286 287define i16 @umax_umin_cmax_ugt_cmin(i16 %x) {288; CHECK-LABEL: define i16 @umax_umin_cmax_ugt_cmin(289; CHECK-SAME: i16 [[X:%.*]]) {290; CHECK-NEXT: ret i16 127291;292 %min = call i16 @llvm.umin.i16(i16 %x, i16 126)293 %max = call i16 @llvm.umax.i16(i16 %min, i16 127)294 ret i16 %max295}296 297define i16 @smax_smin_variables(i16 %x, i16 %y, i16 %z) {298; CHECK-LABEL: define i16 @smax_smin_variables(299; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {300; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[X]], i16 [[Y]])301; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[MIN]], i16 [[Z]])302; CHECK-NEXT: ret i16 [[MAX]]303;304 %min = call i16 @llvm.smin.i16(i16 %x, i16 %y)305 %max = call i16 @llvm.smax.i16(i16 %min, i16 %z)306 ret i16 %max307}308 309define i16 @umax_umin_variables(i16 %x, i16 %y, i16 %z) {310; CHECK-LABEL: define i16 @umax_umin_variables(311; CHECK-SAME: i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {312; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[X]], i16 [[Y]])313; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[MIN]], i16 [[Z]])314; CHECK-NEXT: ret i16 [[MAX]]315;316 %min = call i16 @llvm.umin.i16(i16 %x, i16 %y)317 %max = call i16 @llvm.umax.i16(i16 %min, i16 %z)318 ret i16 %max319}320 321define i16 @smin_smax(i16 %x) {322; CHECK-LABEL: define i16 @smin_smax(323; CHECK-SAME: i16 [[X:%.*]]) {324; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)325; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[MAX]], i16 127)326; CHECK-NEXT: ret i16 [[MIN]]327;328 %max = call i16 @llvm.smax.i16(i16 %x, i16 -128)329 %min = call i16 @llvm.smin.i16(i16 %max, i16 127)330 ret i16 %min331}332 333define i16 @umin_umax(i16 %x) {334; CHECK-LABEL: define i16 @umin_umax(335; CHECK-SAME: i16 [[X:%.*]]) {336; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)337; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[MAX]], i16 255)338; CHECK-NEXT: ret i16 [[MIN]]339;340 %max = call i16 @llvm.umax.i16(i16 %x, i16 127)341 %min = call i16 @llvm.umin.i16(i16 %max, i16 255)342 ret i16 %min343}344 345define i16 @smin_umax(i16 %x) {346; CHECK-LABEL: define i16 @smin_umax(347; CHECK-SAME: i16 [[X:%.*]]) {348; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.umax.i16(i16 [[X]], i16 127)349; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.smin.i16(i16 [[MAX]], i16 255)350; CHECK-NEXT: ret i16 [[MIN]]351;352 %max = call i16 @llvm.umax.i16(i16 %x, i16 127)353 %min = call i16 @llvm.smin.i16(i16 %max, i16 255)354 ret i16 %min355}356 357define i16 @umin_smax(i16 %x) {358; CHECK-LABEL: define i16 @umin_smax(359; CHECK-SAME: i16 [[X:%.*]]) {360; CHECK-NEXT: [[MAX:%.*]] = call i16 @llvm.smax.i16(i16 [[X]], i16 -128)361; CHECK-NEXT: [[MIN:%.*]] = call i16 @llvm.umin.i16(i16 [[MAX]], i16 127)362; CHECK-NEXT: ret i16 [[MIN]]363;364 %max = call i16 @llvm.smax.i16(i16 %x, i16 -128)365 %min = call i16 @llvm.umin.i16(i16 %max, i16 127)366 ret i16 %min367}368