472 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=ANY,NO-FLOAT-SHRINK3; RUN: opt < %s -passes=instcombine -enable-double-float-shrink -S | FileCheck %s --check-prefixes=ANY,DO-FLOAT-SHRINK4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"6 7declare double @cos(double)8declare double @llvm.cos.f64(double)9declare float @cosf(float)10declare float @llvm.cos.f32(float)11 12declare double @sin(double)13declare double @llvm.sin.f64(double)14declare float @sinf(float)15declare float @llvm.sin.f32(float)16 17declare double @tan(double)18declare fp128 @tanl(fp128)19 20declare double @fabs(double)21declare double @llvm.fabs.f64(double)22declare float @fabsf(float)23declare float @llvm.fabs.f32(float)24 25declare double @llvm.copysign(double, double)26declare float @llvm.copysign.f32(float, float)27 28; cos(-x) -> cos(x);29 30define double @cos_negated_arg(double %x) {31; ANY-LABEL: @cos_negated_arg(32; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])33; ANY-NEXT: ret double [[COS]]34;35 %neg = fsub double -0.0, %x36 %r = call double @cos(double %neg)37 ret double %r38}39 40define double @cos_negated_arg_tail(double %x) {41; ANY-LABEL: @cos_negated_arg_tail(42; ANY-NEXT: [[COS:%.*]] = tail call double @cos(double [[X:%.*]])43; ANY-NEXT: ret double [[COS]]44;45 %neg = fsub double -0.0, %x46 %r = tail call double @cos(double %neg)47 ret double %r48}49 50define double @cos_negated_arg_musttail(double %x) {51; ANY-LABEL: @cos_negated_arg_musttail(52; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]53; ANY-NEXT: [[R:%.*]] = musttail call double @cos(double [[NEG]])54; ANY-NEXT: ret double [[R]]55;56 %neg = fsub double -0.0, %x57 %r = musttail call double @cos(double %neg)58 ret double %r59}60 61define double @cos_unary_negated_arg(double %x) {62; ANY-LABEL: @cos_unary_negated_arg(63; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])64; ANY-NEXT: ret double [[COS]]65;66 %neg = fneg double %x67 %r = call double @cos(double %neg)68 ret double %r69}70 71define float @cosf_negated_arg(float %x) {72; ANY-LABEL: @cosf_negated_arg(73; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])74; ANY-NEXT: ret float [[COS]]75;76 %neg = fsub float -0.0, %x77 %r = call float @cosf(float %neg)78 ret float %r79}80 81define float @cosf_unary_negated_arg(float %x) {82; ANY-LABEL: @cosf_unary_negated_arg(83; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])84; ANY-NEXT: ret float [[COS]]85;86 %neg = fneg float %x87 %r = call float @cosf(float %neg)88 ret float %r89}90 91define float @cosf_negated_arg_FMF(float %x) {92; ANY-LABEL: @cosf_negated_arg_FMF(93; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])94; ANY-NEXT: ret float [[COS]]95;96 %neg = fsub float -0.0, %x97 %r = call nnan reassoc float @cosf(float %neg)98 ret float %r99}100 101define float @cosf_unary_negated_arg_FMF(float %x) {102; ANY-LABEL: @cosf_unary_negated_arg_FMF(103; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])104; ANY-NEXT: ret float [[COS]]105;106 %neg = fneg float %x107 %r = call nnan reassoc float @cosf(float %neg)108 ret float %r109}110 111; cos(fabs(x)) -> cos(x)112 113define double @cos_unary_fabs_arg(double %x) {114; ANY-LABEL: @cos_unary_fabs_arg(115; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])116; ANY-NEXT: ret double [[COS]]117;118 %fabs = tail call double @llvm.fabs.f64(double %x)119 %r = call double @cos(double %fabs)120 ret double %r121}122 123define float @cosf_unary_fabs_arg(float %x) {124; ANY-LABEL: @cosf_unary_fabs_arg(125; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])126; ANY-NEXT: ret float [[COS]]127;128 %fabs = tail call float @llvm.fabs.f32(float %x)129 %r = call float @cosf(float %fabs)130 ret float %r131}132 133define float @cosf_unary_fabs_arg_FMF(float %x) {134; ANY-LABEL: @cosf_unary_fabs_arg_FMF(135; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])136; ANY-NEXT: ret float [[COS]]137;138 %fabs = tail call float @llvm.fabs.f32(float %x)139 %r = call nnan reassoc float @cosf(float %fabs)140 ret float %r141}142 143; cos(copysign(x, y)) -> cos(x)144 145define double @cos_copysign_arg(double %x, double %y) {146; ANY-LABEL: @cos_copysign_arg(147; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]])148; ANY-NEXT: ret double [[COS]]149;150 %copysign = tail call double @llvm.copysign(double %x, double %y)151 %r = call double @cos(double %copysign)152 ret double %r153}154 155 156define float @cosf_unary_copysign_arg(float %x) {157; ANY-LABEL: @cosf_unary_copysign_arg(158; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]])159; ANY-NEXT: ret float [[COS]]160;161 %copysign = tail call float @llvm.copysign.f32(float %x, float 1.0)162 %r = call float @cosf(float %copysign)163 ret float %r164}165 166define float @cosf_copysign_arg_FMF(float %x, float %y) {167; ANY-LABEL: @cosf_copysign_arg_FMF(168; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])169; ANY-NEXT: ret float [[COS]]170;171 %copysign = tail call float @llvm.copysign.f32(float %x, float %y)172 %r = call nnan reassoc float @cosf(float %copysign)173 ret float %r174}175 176; sin(-x) -> -sin(x);177 178define double @sin_negated_arg(double %x) {179; ANY-LABEL: @sin_negated_arg(180; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])181; ANY-NEXT: [[R:%.*]] = fneg double [[TMP1]]182; ANY-NEXT: ret double [[R]]183;184 %neg = fsub double -0.0, %x185 %r = call double @sin(double %neg)186 ret double %r187}188 189define double @sin_unary_negated_arg(double %x) {190; ANY-LABEL: @sin_unary_negated_arg(191; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])192; ANY-NEXT: [[R:%.*]] = fneg double [[TMP1]]193; ANY-NEXT: ret double [[R]]194;195 %neg = fneg double %x196 %r = call double @sin(double %neg)197 ret double %r198}199 200define double @sin_unary_negated_arg_musttail(double %x) {201; ANY-LABEL: @sin_unary_negated_arg_musttail(202; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]203; ANY-NEXT: [[R:%.*]] = musttail call double @sin(double [[NEG]])204; ANY-NEXT: ret double [[R]]205;206 %neg = fneg double %x207 %r = musttail call double @sin(double %neg)208 ret double %r209}210 211define float @sinf_negated_arg(float %x) {212; ANY-LABEL: @sinf_negated_arg(213; ANY-NEXT: [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])214; ANY-NEXT: [[R:%.*]] = fneg float [[TMP1]]215; ANY-NEXT: ret float [[R]]216;217 %neg = fsub float -0.0, %x218 %r = call float @sinf(float %neg)219 ret float %r220}221 222define float @sinf_unary_negated_arg(float %x) {223; ANY-LABEL: @sinf_unary_negated_arg(224; ANY-NEXT: [[TMP1:%.*]] = call float @sinf(float [[X:%.*]])225; ANY-NEXT: [[R:%.*]] = fneg float [[TMP1]]226; ANY-NEXT: ret float [[R]]227;228 %neg = fneg float %x229 %r = call float @sinf(float %neg)230 ret float %r231}232 233define float @sinf_negated_arg_FMF(float %x) {234; ANY-LABEL: @sinf_negated_arg_FMF(235; ANY-NEXT: [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])236; ANY-NEXT: [[R:%.*]] = fneg nnan afn float [[TMP1]]237; ANY-NEXT: ret float [[R]]238;239 %neg = fsub ninf float -0.0, %x240 %r = call afn nnan float @sinf(float %neg)241 ret float %r242}243 244define float @sinf_unary_negated_arg_FMF(float %x) {245; ANY-LABEL: @sinf_unary_negated_arg_FMF(246; ANY-NEXT: [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]])247; ANY-NEXT: [[R:%.*]] = fneg nnan afn float [[TMP1]]248; ANY-NEXT: ret float [[R]]249;250 %neg = fneg ninf float %x251 %r = call afn nnan float @sinf(float %neg)252 ret float %r253}254 255declare void @use(double)256 257define double @sin_negated_arg_extra_use(double %x) {258; ANY-LABEL: @sin_negated_arg_extra_use(259; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]260; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]])261; ANY-NEXT: call void @use(double [[NEG]])262; ANY-NEXT: ret double [[R]]263;264 %neg = fsub double -0.0, %x265 %r = call double @sin(double %neg)266 call void @use(double %neg)267 ret double %r268}269 270define double @sin_unary_negated_arg_extra_use(double %x) {271; ANY-LABEL: @sin_unary_negated_arg_extra_use(272; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]273; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]])274; ANY-NEXT: call void @use(double [[NEG]])275; ANY-NEXT: ret double [[R]]276;277 %neg = fneg double %x278 %r = call double @sin(double %neg)279 call void @use(double %neg)280 ret double %r281}282 283; -sin(-x) --> sin(x)284; PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458285 286define double @neg_sin_negated_arg(double %x) {287; ANY-LABEL: @neg_sin_negated_arg(288; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])289; ANY-NEXT: ret double [[TMP1]]290;291 %neg = fsub double -0.0, %x292 %r = call double @sin(double %neg)293 %rn = fsub double -0.0, %r294 ret double %rn295}296 297define double @unary_neg_sin_unary_negated_arg(double %x) {298; ANY-LABEL: @unary_neg_sin_unary_negated_arg(299; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])300; ANY-NEXT: ret double [[TMP1]]301;302 %neg = fneg double %x303 %r = call double @sin(double %neg)304 %rn = fneg double %r305 ret double %rn306}307 308define double @neg_sin_unary_negated_arg(double %x) {309; ANY-LABEL: @neg_sin_unary_negated_arg(310; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])311; ANY-NEXT: ret double [[TMP1]]312;313 %neg = fsub double -0.0, %x314 %r = call double @sin(double %neg)315 %rn = fneg double %r316 ret double %rn317}318 319define double @unary_neg_sin_negated_arg(double %x) {320; ANY-LABEL: @unary_neg_sin_negated_arg(321; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]])322; ANY-NEXT: ret double [[TMP1]]323;324 %neg = fneg double %x325 %r = call double @sin(double %neg)326 %rn = fsub double -0.0, %r327 ret double %rn328}329 330; tan(-x) -> -tan(x);331 332define double @tan_negated_arg(double %x) {333; ANY-LABEL: @tan_negated_arg(334; ANY-NEXT: [[TMP1:%.*]] = call double @tan(double [[X:%.*]])335; ANY-NEXT: [[R:%.*]] = fneg double [[TMP1]]336; ANY-NEXT: ret double [[R]]337;338 %neg = fsub double -0.0, %x339 %r = call double @tan(double %neg)340 ret double %r341}342 343define double @tan_negated_arg_tail(double %x) {344; ANY-LABEL: @tan_negated_arg_tail(345; ANY-NEXT: [[TMP1:%.*]] = tail call double @tan(double [[X:%.*]])346; ANY-NEXT: [[R:%.*]] = fneg double [[TMP1]]347; ANY-NEXT: ret double [[R]]348;349 %neg = fsub double -0.0, %x350 %r = tail call double @tan(double %neg)351 ret double %r352}353define double @tan_negated_arg_musttail(double %x) {354; ANY-LABEL: @tan_negated_arg_musttail(355; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]]356; ANY-NEXT: [[R:%.*]] = musttail call double @tan(double [[NEG]])357; ANY-NEXT: ret double [[R]]358;359 %neg = fsub double -0.0, %x360 %r = musttail call double @tan(double %neg)361 ret double %r362}363 364define double @tan_unary_negated_arg(double %x) {365; ANY-LABEL: @tan_unary_negated_arg(366; ANY-NEXT: [[TMP1:%.*]] = call double @tan(double [[X:%.*]])367; ANY-NEXT: [[R:%.*]] = fneg double [[TMP1]]368; ANY-NEXT: ret double [[R]]369;370 %neg = fneg double %x371 %r = call double @tan(double %neg)372 ret double %r373}374 375; tanl(-x) -> -tanl(x);376 377define fp128 @tanl_negated_arg(fp128 %x) {378; ANY-LABEL: @tanl_negated_arg(379; ANY-NEXT: [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])380; ANY-NEXT: [[R:%.*]] = fneg fp128 [[TMP1]]381; ANY-NEXT: ret fp128 [[R]]382;383 %neg = fsub fp128 0xL00000000000000008000000000000000, %x384 %r = call fp128 @tanl(fp128 %neg)385 ret fp128 %r386}387 388define fp128 @tanl_unary_negated_arg(fp128 %x) {389; ANY-LABEL: @tanl_unary_negated_arg(390; ANY-NEXT: [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]])391; ANY-NEXT: [[R:%.*]] = fneg fp128 [[TMP1]]392; ANY-NEXT: ret fp128 [[R]]393;394 %neg = fneg fp128 %x395 %r = call fp128 @tanl(fp128 %neg)396 ret fp128 %r397}398 399define float @negated_and_shrinkable_libcall(float %f) {400; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(401; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double402; NO-FLOAT-SHRINK-NEXT: [[COS1:%.*]] = call double @cos(double [[CONV1]])403; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS1]] to float404; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]405;406; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall(407; DO-FLOAT-SHRINK-NEXT: [[COSF:%.*]] = call float @cosf(float [[F:%.*]])408; DO-FLOAT-SHRINK-NEXT: ret float [[COSF]]409;410 %conv1 = fpext float %f to double411 %neg = fsub double -0.0, %conv1412 %cos = call double @cos(double %neg)413 %conv2 = fptrunc double %cos to float414 ret float %conv2415}416 417define float @unary_negated_and_shrinkable_libcall(float %f) {418; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(419; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double420; NO-FLOAT-SHRINK-NEXT: [[COS1:%.*]] = call double @cos(double [[CONV1]])421; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS1]] to float422; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]423;424; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall(425; DO-FLOAT-SHRINK-NEXT: [[COSF:%.*]] = call float @cosf(float [[F:%.*]])426; DO-FLOAT-SHRINK-NEXT: ret float [[COSF]]427;428 %conv1 = fpext float %f to double429 %neg = fneg double %conv1430 %cos = call double @cos(double %neg)431 %conv2 = fptrunc double %cos to float432 ret float %conv2433}434 435; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too?436 437define float @negated_and_shrinkable_intrinsic(float %f) {438; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_intrinsic(439; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double440; NO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])441; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float442; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]443;444; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_intrinsic(445; DO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])446; DO-FLOAT-SHRINK-NEXT: ret float [[COS]]447;448 %conv1 = fpext float %f to double449 %neg = fsub double -0.0, %conv1450 %cos = call double @llvm.cos.f64(double %neg)451 %conv2 = fptrunc double %cos to float452 ret float %conv2453}454 455define float @unary_negated_and_shrinkable_intrinsic(float %f) {456; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_intrinsic(457; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double458; NO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]])459; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float460; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]]461;462; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_intrinsic(463; DO-FLOAT-SHRINK-NEXT: [[COS:%.*]] = call float @llvm.cos.f32(float [[F:%.*]])464; DO-FLOAT-SHRINK-NEXT: ret float [[COS]]465;466 %conv1 = fpext float %f to double467 %neg = fneg double %conv1468 %cos = call double @llvm.cos.f64(double %neg)469 %conv2 = fptrunc double %cos to float470 ret float %conv2471}472