564 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare float @llvm.maxnum.f32(float %a, float %b)5declare float @llvm.minnum.f32(float %a, float %b)6declare float @llvm.maximum.f32(float %a, float %b)7declare float @llvm.minimum.f32(float %a, float %b)8declare i32 @llvm.smax.i32(i32 %a, i32 %b)9declare i32 @llvm.smin.i32(i32 %a, i32 %b)10declare i32 @llvm.umax.i32(i32 %a, i32 %b)11declare i32 @llvm.umin.i32(i32 %a, i32 %b)12declare i16 @llvm.sadd.sat.i16(i16 %a, i16 %b)13declare i16 @llvm.uadd.sat.i16(i16 %a, i16 %b)14declare {i16, i1} @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)15declare {i16, i1} @llvm.uadd.with.overflow.i16(i16 %a, i16 %b)16declare {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b)17declare {i16, i1} @llvm.umul.with.overflow.i16(i16 %a, i16 %b)18declare i16 @llvm.smul.fix.i16(i16 %a, i16 %b, i32 %scale)19declare i16 @llvm.umul.fix.i16(i16 %a, i16 %b, i32 %scale)20declare i16 @llvm.smul.fix.sat.i16(i16 %a, i16 %b, i32 %scale)21declare i16 @llvm.umul.fix.sat.i16(i16 %a, i16 %b, i32 %scale)22declare float @llvm.fma.f32(float %a, float %b, float %c)23declare float @llvm.fmuladd.f32(float %a, float %b, float %c)24 25define i8 @fold_select_mul(i1 %c, i8 %a, i8 %b) {26; CHECK-LABEL: define i8 @fold_select_mul(27; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {28; CHECK-NEXT: [[RET:%.*]] = mul i8 [[B]], [[A]]29; CHECK-NEXT: ret i8 [[RET]]30;31 %s0 = select i1 %c, i8 %a, i8 %b32 %s1 = select i1 %c, i8 %b, i8 %a33 %ret = mul i8 %s1, %s034 ret i8 %ret35}36 37define i8 @fold_select_mul_nsw_nuw_preserve(i1 %c, i8 %a, i8 %b) {38; CHECK-LABEL: define i8 @fold_select_mul_nsw_nuw_preserve(39; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {40; CHECK-NEXT: [[RET:%.*]] = mul nuw nsw i8 [[B]], [[A]]41; CHECK-NEXT: ret i8 [[RET]]42;43 %s0 = select i1 %c, i8 %a, i8 %b44 %s1 = select i1 %c, i8 %b, i8 %a45 %ret = mul nsw nuw i8 %s1, %s046 ret i8 %ret47}48 49define <2 x i4> @fold_select_mul_vec2(i1 %c, <2 x i4> %a, <2 x i4> %b) {50; CHECK-LABEL: define <2 x i4> @fold_select_mul_vec2(51; CHECK-SAME: i1 [[C:%.*]], <2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {52; CHECK-NEXT: [[RET:%.*]] = mul <2 x i4> [[B]], [[A]]53; CHECK-NEXT: ret <2 x i4> [[RET]]54;55 %s0 = select i1 %c, <2 x i4> %a, <2 x i4> %b56 %s1 = select i1 %c, <2 x i4> %b, <2 x i4> %a57 %ret = mul <2 x i4> %s1, %s058 ret <2 x i4> %ret59}60 61define i8 @fold_select_add(i1 %c, i8 %a, i8 %b) {62; CHECK-LABEL: define i8 @fold_select_add(63; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {64; CHECK-NEXT: [[RET:%.*]] = add i8 [[B]], [[A]]65; CHECK-NEXT: ret i8 [[RET]]66;67 %s0 = select i1 %c, i8 %a, i8 %b68 %s1 = select i1 %c, i8 %b, i8 %a69 %ret = add i8 %s1, %s070 ret i8 %ret71}72 73define <2 x i4> @fold_select_add_vec2(i1 %c, <2 x i4> %a, <2 x i4> %b) {74; CHECK-LABEL: define <2 x i4> @fold_select_add_vec2(75; CHECK-SAME: i1 [[C:%.*]], <2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {76; CHECK-NEXT: [[RET:%.*]] = add <2 x i4> [[B]], [[A]]77; CHECK-NEXT: ret <2 x i4> [[RET]]78;79 %s0 = select i1 %c, <2 x i4> %a, <2 x i4> %b80 %s1 = select i1 %c, <2 x i4> %b, <2 x i4> %a81 %ret = add <2 x i4> %s1, %s082 ret <2 x i4> %ret83}84 85define i8 @fold_select_and(i1 %c, i8 %a, i8 %b) {86; CHECK-LABEL: define i8 @fold_select_and(87; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {88; CHECK-NEXT: [[RET:%.*]] = and i8 [[B]], [[A]]89; CHECK-NEXT: ret i8 [[RET]]90;91 %s0 = select i1 %c, i8 %a, i8 %b92 %s1 = select i1 %c, i8 %b, i8 %a93 %ret = and i8 %s1, %s094 ret i8 %ret95}96 97define <2 x i4> @fold_select_and_vec2(i1 %c, <2 x i4> %a, <2 x i4> %b) {98; CHECK-LABEL: define <2 x i4> @fold_select_and_vec2(99; CHECK-SAME: i1 [[C:%.*]], <2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {100; CHECK-NEXT: [[RET:%.*]] = and <2 x i4> [[B]], [[A]]101; CHECK-NEXT: ret <2 x i4> [[RET]]102;103 %s0 = select i1 %c, <2 x i4> %a, <2 x i4> %b104 %s1 = select i1 %c, <2 x i4> %b, <2 x i4> %a105 %ret = and <2 x i4> %s1, %s0106 ret <2 x i4> %ret107}108 109define i8 @fold_select_or(i1 %c, i8 %a, i8 %b) {110; CHECK-LABEL: define i8 @fold_select_or(111; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {112; CHECK-NEXT: [[RET:%.*]] = or i8 [[B]], [[A]]113; CHECK-NEXT: ret i8 [[RET]]114;115 %s0 = select i1 %c, i8 %a, i8 %b116 %s1 = select i1 %c, i8 %b, i8 %a117 %ret = or i8 %s1, %s0118 ret i8 %ret119}120 121define <2 x i4> @fold_select_or_vec2(i1 %c, <2 x i4> %a, <2 x i4> %b) {122; CHECK-LABEL: define <2 x i4> @fold_select_or_vec2(123; CHECK-SAME: i1 [[C:%.*]], <2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {124; CHECK-NEXT: [[RET:%.*]] = or <2 x i4> [[B]], [[A]]125; CHECK-NEXT: ret <2 x i4> [[RET]]126;127 %s0 = select i1 %c, <2 x i4> %a, <2 x i4> %b128 %s1 = select i1 %c, <2 x i4> %b, <2 x i4> %a129 %ret = or <2 x i4> %s1, %s0130 ret <2 x i4> %ret131}132 133define i8 @fold_select_xor(i1 %c, i8 %a, i8 %b) {134; CHECK-LABEL: define i8 @fold_select_xor(135; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {136; CHECK-NEXT: [[RET:%.*]] = xor i8 [[B]], [[A]]137; CHECK-NEXT: ret i8 [[RET]]138;139 %s0 = select i1 %c, i8 %a, i8 %b140 %s1 = select i1 %c, i8 %b, i8 %a141 %ret = xor i8 %s1, %s0142 ret i8 %ret143}144 145define <2 x i4> @fold_select_xor_vec2(i1 %c, <2 x i4> %a, <2 x i4> %b) {146; CHECK-LABEL: define <2 x i4> @fold_select_xor_vec2(147; CHECK-SAME: i1 [[C:%.*]], <2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {148; CHECK-NEXT: [[RET:%.*]] = xor <2 x i4> [[B]], [[A]]149; CHECK-NEXT: ret <2 x i4> [[RET]]150;151 %s0 = select i1 %c, <2 x i4> %a, <2 x i4> %b152 %s1 = select i1 %c, <2 x i4> %b, <2 x i4> %a153 %ret = xor <2 x i4> %s1, %s0154 ret <2 x i4> %ret155}156 157define float @fold_select_fadd(i1 %c, float %a, float %b) {158; CHECK-LABEL: define float @fold_select_fadd(159; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {160; CHECK-NEXT: [[RET:%.*]] = fadd float [[B]], [[A]]161; CHECK-NEXT: ret float [[RET]]162;163 %s0 = select i1 %c, float %a, float %b164 %s1 = select i1 %c, float %b, float %a165 %ret = fadd float %s1, %s0166 ret float %ret167}168 169define float @fold_select_fadd_nnan(i1 %c, float %a, float %b) {170; CHECK-LABEL: define float @fold_select_fadd_nnan(171; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {172; CHECK-NEXT: [[RET:%.*]] = fadd nnan float [[B]], [[A]]173; CHECK-NEXT: ret float [[RET]]174;175 %s0 = select i1 %c, float %a, float %b176 %s1 = select i1 %c, float %b, float %a177 %ret = fadd nnan float %s1, %s0178 ret float %ret179}180 181define <2 x float> @fold_select_fadd_vec2(i1 %c, <2 x float> %a, <2 x float> %b) {182; CHECK-LABEL: define <2 x float> @fold_select_fadd_vec2(183; CHECK-SAME: i1 [[C:%.*]], <2 x float> [[A:%.*]], <2 x float> [[B:%.*]]) {184; CHECK-NEXT: [[RET:%.*]] = fadd <2 x float> [[B]], [[A]]185; CHECK-NEXT: ret <2 x float> [[RET]]186;187 %s0 = select i1 %c, <2 x float> %a, <2 x float> %b188 %s1 = select i1 %c, <2 x float> %b, <2 x float> %a189 %ret = fadd <2 x float> %s1, %s0190 ret <2 x float> %ret191}192 193define float @fold_select_fmul(i1 %c, float %a, float %b) {194; CHECK-LABEL: define float @fold_select_fmul(195; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {196; CHECK-NEXT: [[RET:%.*]] = fmul float [[B]], [[A]]197; CHECK-NEXT: ret float [[RET]]198;199 %s0 = select i1 %c, float %a, float %b200 %s1 = select i1 %c, float %b, float %a201 %ret = fmul float %s1, %s0202 ret float %ret203}204 205define <2 x float> @fold_select_fmul_vec2(i1 %c, <2 x float> %a, <2 x float> %b) {206; CHECK-LABEL: define <2 x float> @fold_select_fmul_vec2(207; CHECK-SAME: i1 [[C:%.*]], <2 x float> [[A:%.*]], <2 x float> [[B:%.*]]) {208; CHECK-NEXT: [[RET:%.*]] = fmul <2 x float> [[B]], [[A]]209; CHECK-NEXT: ret <2 x float> [[RET]]210;211 %s0 = select i1 %c, <2 x float> %a, <2 x float> %b212 %s1 = select i1 %c, <2 x float> %b, <2 x float> %a213 %ret = fmul <2 x float> %s1, %s0214 ret <2 x float> %ret215}216 217;218 219define float @fold_select_maxnum(i1 %c, float %a, float %b) {220; CHECK-LABEL: define float @fold_select_maxnum(221; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {222; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maxnum.f32(float [[B]], float [[A]])223; CHECK-NEXT: ret float [[RET]]224;225 %s0 = select i1 %c, float %a, float %b226 %s1 = select i1 %c, float %b, float %a227 %ret = call float @llvm.maxnum.f32(float %s1, float %s0)228 ret float %ret229}230 231define float @fold_select_minnum(i1 %c, float %a, float %b) {232; CHECK-LABEL: define float @fold_select_minnum(233; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {234; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minnum.f32(float [[B]], float [[A]])235; CHECK-NEXT: ret float [[RET]]236;237 %s0 = select i1 %c, float %a, float %b238 %s1 = select i1 %c, float %b, float %a239 %ret = call float @llvm.minnum.f32(float %s1, float %s0)240 ret float %ret241}242 243define float @fold_select_maximum(i1 %c, float %a, float %b) {244; CHECK-LABEL: define float @fold_select_maximum(245; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {246; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maximum.f32(float [[B]], float [[A]])247; CHECK-NEXT: ret float [[RET]]248;249 %s0 = select i1 %c, float %a, float %b250 %s1 = select i1 %c, float %b, float %a251 %ret = call float @llvm.maximum.f32(float %s1, float %s0)252 ret float %ret253}254 255define float @fold_select_minimum(i1 %c, float %a, float %b) {256; CHECK-LABEL: define float @fold_select_minimum(257; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) {258; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minimum.f32(float [[B]], float [[A]])259; CHECK-NEXT: ret float [[RET]]260;261 %s0 = select i1 %c, float %a, float %b262 %s1 = select i1 %c, float %b, float %a263 %ret = call float @llvm.minimum.f32(float %s1, float %s0)264 ret float %ret265}266 267define i32 @fold_select_smax(i1 %c, i32 %a, i32 %b) {268; CHECK-LABEL: define i32 @fold_select_smax(269; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {270; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smax.i32(i32 [[B]], i32 [[A]])271; CHECK-NEXT: ret i32 [[RET]]272;273 %s0 = select i1 %c, i32 %a, i32 %b274 %s1 = select i1 %c, i32 %b, i32 %a275 %ret = call i32 @llvm.smax.i32(i32 %s1, i32 %s0)276 ret i32 %ret277}278 279define i32 @fold_select_smin(i1 %c, i32 %a, i32 %b) {280; CHECK-LABEL: define i32 @fold_select_smin(281; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {282; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smin.i32(i32 [[B]], i32 [[A]])283; CHECK-NEXT: ret i32 [[RET]]284;285 %s0 = select i1 %c, i32 %a, i32 %b286 %s1 = select i1 %c, i32 %b, i32 %a287 %ret = call i32 @llvm.smin.i32(i32 %s1, i32 %s0)288 ret i32 %ret289}290 291define i32 @fold_select_umax(i1 %c, i32 %a, i32 %b) {292; CHECK-LABEL: define i32 @fold_select_umax(293; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {294; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[A]])295; CHECK-NEXT: ret i32 [[RET]]296;297 %s0 = select i1 %c, i32 %a, i32 %b298 %s1 = select i1 %c, i32 %b, i32 %a299 %ret = call i32 @llvm.umax.i32(i32 %s1, i32 %s0)300 ret i32 %ret301}302 303define i32 @fold_select_umin(i1 %c, i32 %a, i32 %b) {304; CHECK-LABEL: define i32 @fold_select_umin(305; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {306; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[B]], i32 [[A]])307; CHECK-NEXT: ret i32 [[RET]]308;309 %s0 = select i1 %c, i32 %a, i32 %b310 %s1 = select i1 %c, i32 %b, i32 %a311 %ret = call i32 @llvm.umin.i32(i32 %s1, i32 %s0)312 ret i32 %ret313}314 315define i16 @fold_select_sadd_sat(i1 %c, i16 %a, i16 %b) {316; CHECK-LABEL: define i16 @fold_select_sadd_sat(317; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]) {318; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.sadd.sat.i16(i16 [[B]], i16 [[A]])319; CHECK-NEXT: ret i16 [[RET]]320;321 %s0 = select i1 %c, i16 %a, i16 %b322 %s1 = select i1 %c, i16 %b, i16 %a323 %ret = call i16 @llvm.sadd.sat.i16(i16 %s1, i16 %s0)324 ret i16 %ret325}326 327define i16 @fold_select_uadd_sat(i1 %c, i16 %a, i16 %b) {328; CHECK-LABEL: define i16 @fold_select_uadd_sat(329; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]) {330; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[B]], i16 [[A]])331; CHECK-NEXT: ret i16 [[RET]]332;333 %s0 = select i1 %c, i16 %a, i16 %b334 %s1 = select i1 %c, i16 %b, i16 %a335 %ret = call i16 @llvm.uadd.sat.i16(i16 %s1, i16 %s0)336 ret i16 %ret337}338 339define i16 @fold_select_sadd_with_overflow(i1 %c, i16 %a, i16 %b) {340; CHECK-LABEL: define i16 @fold_select_sadd_with_overflow(341; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]) {342; CHECK-NEXT: [[RES:%.*]] = call { i16, i1 } @llvm.sadd.with.overflow.i16(i16 [[B]], i16 [[A]])343; CHECK-NEXT: [[OBIT:%.*]] = extractvalue { i16, i1 } [[RES]], 1344; CHECK-NEXT: br i1 [[OBIT]], label [[OVERFLOW:%.*]], label [[NORMAL:%.*]]345; CHECK: overflow:346; CHECK-NEXT: ret i16 0347; CHECK: normal:348; CHECK-NEXT: [[SUM:%.*]] = extractvalue { i16, i1 } [[RES]], 0349; CHECK-NEXT: ret i16 [[SUM]]350;351 %s0 = select i1 %c, i16 %a, i16 %b352 %s1 = select i1 %c, i16 %b, i16 %a353 %res = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %s1, i16 %s0)354 %obit = extractvalue {i16, i1} %res, 1355 br i1 %obit, label %overflow, label %normal356overflow:357 ret i16 0358normal:359 %sum = extractvalue {i16, i1} %res, 0360 ret i16 %sum361}362 363define i16 @fold_select_uadd_with_overflow(i1 %c, i16 %a, i16 %b) {364; CHECK-LABEL: define i16 @fold_select_uadd_with_overflow(365; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]) {366; CHECK-NEXT: [[RES:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 [[B]], i16 [[A]])367; CHECK-NEXT: [[OBIT:%.*]] = extractvalue { i16, i1 } [[RES]], 1368; CHECK-NEXT: br i1 [[OBIT]], label [[OVERFLOW:%.*]], label [[NORMAL:%.*]]369; CHECK: overflow:370; CHECK-NEXT: ret i16 0371; CHECK: normal:372; CHECK-NEXT: [[SUM:%.*]] = extractvalue { i16, i1 } [[RES]], 0373; CHECK-NEXT: ret i16 [[SUM]]374;375 %s0 = select i1 %c, i16 %a, i16 %b376 %s1 = select i1 %c, i16 %b, i16 %a377 %res = call {i16, i1} @llvm.uadd.with.overflow.i16(i16 %s1, i16 %s0)378 %obit = extractvalue {i16, i1} %res, 1379 br i1 %obit, label %overflow, label %normal380overflow:381 ret i16 0382normal:383 %sum = extractvalue {i16, i1} %res, 0384 ret i16 %sum385}386 387define i16 @fold_select_smul_with_overflow(i1 %c, i16 %a, i16 %b) {388; CHECK-LABEL: define i16 @fold_select_smul_with_overflow(389; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]) {390; CHECK-NEXT: [[RES:%.*]] = call { i16, i1 } @llvm.smul.with.overflow.i16(i16 [[B]], i16 [[A]])391; CHECK-NEXT: [[OBIT:%.*]] = extractvalue { i16, i1 } [[RES]], 1392; CHECK-NEXT: br i1 [[OBIT]], label [[OVERFLOW:%.*]], label [[NORMAL:%.*]]393; CHECK: overflow:394; CHECK-NEXT: ret i16 0395; CHECK: normal:396; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i16, i1 } [[RES]], 0397; CHECK-NEXT: ret i16 [[MUL]]398;399 %s0 = select i1 %c, i16 %a, i16 %b400 %s1 = select i1 %c, i16 %b, i16 %a401 %res = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %s1, i16 %s0)402 %obit = extractvalue {i16, i1} %res, 1403 br i1 %obit, label %overflow, label %normal404overflow:405 ret i16 0406normal:407 %mul = extractvalue {i16, i1} %res, 0408 ret i16 %mul409}410 411define i16 @fold_select_umul_with_overflow(i1 %c, i16 %a, i16 %b) {412; CHECK-LABEL: define i16 @fold_select_umul_with_overflow(413; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]]) {414; CHECK-NEXT: [[RES:%.*]] = call { i16, i1 } @llvm.umul.with.overflow.i16(i16 [[B]], i16 [[A]])415; CHECK-NEXT: [[OBIT:%.*]] = extractvalue { i16, i1 } [[RES]], 1416; CHECK-NEXT: br i1 [[OBIT]], label [[OVERFLOW:%.*]], label [[NORMAL:%.*]]417; CHECK: overflow:418; CHECK-NEXT: ret i16 0419; CHECK: normal:420; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i16, i1 } [[RES]], 0421; CHECK-NEXT: ret i16 [[MUL]]422;423 %s0 = select i1 %c, i16 %a, i16 %b424 %s1 = select i1 %c, i16 %b, i16 %a425 %res = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %s1, i16 %s0)426 %obit = extractvalue {i16, i1} %res, 1427 br i1 %obit, label %overflow, label %normal428overflow:429 ret i16 0430normal:431 %mul = extractvalue {i16, i1} %res, 0432 ret i16 %mul433}434 435define i16 @fold_select_smul_fix(i1 %c, i16 %a, i16 %b, i32 %y) {436; CHECK-LABEL: define i16 @fold_select_smul_fix(437; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]], i32 [[Y:%.*]]) {438; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[B]], i16 [[A]], i32 1)439; CHECK-NEXT: ret i16 [[RET]]440;441 %s0 = select i1 %c, i16 %a, i16 %b442 %s1 = select i1 %c, i16 %b, i16 %a443 %ret = call i16 @llvm.smul.fix.i16(i16 %s1, i16 %s0, i32 1)444 ret i16 %ret445}446 447define i16 @fold_select_umul_fix(i1 %c, i16 %a, i16 %b, i32 %y) {448; CHECK-LABEL: define i16 @fold_select_umul_fix(449; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]], i32 [[Y:%.*]]) {450; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[B]], i16 [[A]], i32 1)451; CHECK-NEXT: ret i16 [[RET]]452;453 %s0 = select i1 %c, i16 %a, i16 %b454 %s1 = select i1 %c, i16 %b, i16 %a455 %ret = call i16 @llvm.umul.fix.i16(i16 %s1, i16 %s0, i32 1)456 ret i16 %ret457}458 459define i16 @fold_select_smul_fix_sat(i1 %c, i16 %a, i16 %b, i32 %y) {460; CHECK-LABEL: define i16 @fold_select_smul_fix_sat(461; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]], i32 [[Y:%.*]]) {462; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.smul.fix.sat.i16(i16 [[B]], i16 [[A]], i32 1)463; CHECK-NEXT: ret i16 [[RET]]464;465 %s0 = select i1 %c, i16 %a, i16 %b466 %s1 = select i1 %c, i16 %b, i16 %a467 %ret = call i16 @llvm.smul.fix.sat.i16(i16 %s1, i16 %s0, i32 1)468 ret i16 %ret469}470 471define i16 @fold_select_umul_fix_sat(i1 %c, i16 %a, i16 %b, i32 %y) {472; CHECK-LABEL: define i16 @fold_select_umul_fix_sat(473; CHECK-SAME: i1 [[C:%.*]], i16 [[A:%.*]], i16 [[B:%.*]], i32 [[Y:%.*]]) {474; CHECK-NEXT: [[RET:%.*]] = call i16 @llvm.umul.fix.sat.i16(i16 [[B]], i16 [[A]], i32 1)475; CHECK-NEXT: ret i16 [[RET]]476;477 %s0 = select i1 %c, i16 %a, i16 %b478 %s1 = select i1 %c, i16 %b, i16 %a479 %ret = call i16 @llvm.umul.fix.sat.i16(i16 %s1, i16 %s0, i32 1)480 ret i16 %ret481}482 483define float @fold_select_fma(i1 %c, float %a, float %b, float %y) {484; CHECK-LABEL: define float @fold_select_fma(485; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]], float [[Y:%.*]]) {486; CHECK-NEXT: [[RET:%.*]] = call float @llvm.fma.f32(float [[B]], float [[A]], float [[Y]])487; CHECK-NEXT: ret float [[RET]]488;489 %s0 = select i1 %c, float %a, float %b490 %s1 = select i1 %c, float %b, float %a491 %ret = call float @llvm.fma.f32(float %s1, float %s0, float %y)492 ret float %ret493}494 495define float @fold_select_fmuladd(i1 %c, float %a, float %b, float %y) {496; CHECK-LABEL: define float @fold_select_fmuladd(497; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]], float [[Y:%.*]]) {498; CHECK-NEXT: [[RET:%.*]] = call float @llvm.fmuladd.f32(float [[B]], float [[A]], float [[Y]])499; CHECK-NEXT: ret float [[RET]]500;501 %s0 = select i1 %c, float %a, float %b502 %s1 = select i1 %c, float %b, float %a503 %ret = call float @llvm.fmuladd.f32(float %s1, float %s0, float %y)504 ret float %ret505}506 507;negative tests:508 509define i8 @fold_select_unmatch_mul_neg(i1 %c, i1 %c1, i8 %a, i8 %b) {510; CHECK-LABEL: define i8 @fold_select_unmatch_mul_neg(511; CHECK-SAME: i1 [[C:%.*]], i1 [[C1:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {512; CHECK-NEXT: [[S0:%.*]] = select i1 [[C]], i8 [[A]], i8 [[B]]513; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], i8 [[B]], i8 [[A]]514; CHECK-NEXT: [[RET:%.*]] = mul i8 [[S1]], [[S0]]515; CHECK-NEXT: ret i8 [[RET]]516;517 %s0 = select i1 %c, i8 %a, i8 %b518 %s1 = select i1 %c1, i8 %b, i8 %a519 %ret = mul i8 %s1, %s0520 ret i8 %ret521}522 523define i8 @fold_select_sub_neg(i1 %c, i8 %a, i8 %b) {524; CHECK-LABEL: define i8 @fold_select_sub_neg(525; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) {526; CHECK-NEXT: [[S0:%.*]] = select i1 [[C]], i8 [[A]], i8 [[B]]527; CHECK-NEXT: [[S1:%.*]] = select i1 [[C]], i8 [[B]], i8 [[A]]528; CHECK-NEXT: [[RET:%.*]] = sub i8 [[S1]], [[S0]]529; CHECK-NEXT: ret i8 [[RET]]530;531 %s0 = select i1 %c, i8 %a, i8 %b532 %s1 = select i1 %c, i8 %b, i8 %a533 %ret = sub i8 %s1, %s0534 ret i8 %ret535}536 537define float @fold_select_fma_neg(i1 %c, i1 %c1, float %a, float %b, float %y) {538; CHECK-LABEL: define float @fold_select_fma_neg(539; CHECK-SAME: i1 [[C:%.*]], i1 [[C1:%.*]], float [[A:%.*]], float [[B:%.*]], float [[Y:%.*]]) {540; CHECK-NEXT: [[S0:%.*]] = select i1 [[C]], float [[A]], float [[B]]541; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1]], float [[B]], float [[A]]542; CHECK-NEXT: [[RET:%.*]] = call float @llvm.fma.f32(float [[S1]], float [[S0]], float [[Y]])543; CHECK-NEXT: ret float [[RET]]544;545 %s0 = select i1 %c, float %a, float %b546 %s1 = select i1 %c1, float %b, float %a547 %ret = call float @llvm.fma.f32(float %s1, float %s0, float %y)548 ret float %ret549}550 551define float @fold_select_fma_match_neg(i1 %c, float %a, float %b, float %y) {552; CHECK-LABEL: define float @fold_select_fma_match_neg(553; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]], float [[Y:%.*]]) {554; CHECK-NEXT: [[S0:%.*]] = select i1 [[C]], float [[A]], float [[B]]555; CHECK-NEXT: [[S1:%.*]] = select i1 [[C]], float [[B]], float [[A]]556; CHECK-NEXT: [[RET:%.*]] = call float @llvm.fma.f32(float [[Y]], float [[S0]], float [[S1]])557; CHECK-NEXT: ret float [[RET]]558;559 %s0 = select i1 %c, float %a, float %b560 %s1 = select i1 %c, float %b, float %a561 %ret = call float @llvm.fma.f32(float %y, float %s0, float %s1)562 ret float %ret563}564