brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.6 KiB · a992733 Raw
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