1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s --check-prefixes=ANY,NO-FLOAT-SHRINK 3; RUN: opt < %s -instcombine -enable-double-float-shrink -S | FileCheck %s --check-prefixes=ANY,DO-FLOAT-SHRINK 4 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 20; cos(-x) -> cos(x); 21 22define double @cos_negated_arg(double %x) { 23; ANY-LABEL: @cos_negated_arg( 24; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]]) 25; ANY-NEXT: ret double [[COS]] 26; 27 %neg = fsub double -0.0, %x 28 %r = call double @cos(double %neg) 29 ret double %r 30} 31 32define double @cos_unary_negated_arg(double %x) { 33; ANY-LABEL: @cos_unary_negated_arg( 34; ANY-NEXT: [[COS:%.*]] = call double @cos(double [[X:%.*]]) 35; ANY-NEXT: ret double [[COS]] 36; 37 %neg = fneg double %x 38 %r = call double @cos(double %neg) 39 ret double %r 40} 41 42define float @cosf_negated_arg(float %x) { 43; ANY-LABEL: @cosf_negated_arg( 44; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]]) 45; ANY-NEXT: ret float [[COS]] 46; 47 %neg = fsub float -0.0, %x 48 %r = call float @cosf(float %neg) 49 ret float %r 50} 51 52define float @cosf_unary_negated_arg(float %x) { 53; ANY-LABEL: @cosf_unary_negated_arg( 54; ANY-NEXT: [[COS:%.*]] = call float @cosf(float [[X:%.*]]) 55; ANY-NEXT: ret float [[COS]] 56; 57 %neg = fneg float %x 58 %r = call float @cosf(float %neg) 59 ret float %r 60} 61 62define float @cosf_negated_arg_FMF(float %x) { 63; ANY-LABEL: @cosf_negated_arg_FMF( 64; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]]) 65; ANY-NEXT: ret float [[COS]] 66; 67 %neg = fsub float -0.0, %x 68 %r = call nnan reassoc float @cosf(float %neg) 69 ret float %r 70} 71 72define float @cosf_unary_negated_arg_FMF(float %x) { 73; ANY-LABEL: @cosf_unary_negated_arg_FMF( 74; ANY-NEXT: [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]]) 75; ANY-NEXT: ret float [[COS]] 76; 77 %neg = fneg float %x 78 %r = call nnan reassoc float @cosf(float %neg) 79 ret float %r 80} 81 82; sin(-x) -> -sin(x); 83 84define double @sin_negated_arg(double %x) { 85; ANY-LABEL: @sin_negated_arg( 86; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]]) 87; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] 88; ANY-NEXT: ret double [[TMP2]] 89; 90 %neg = fsub double -0.0, %x 91 %r = call double @sin(double %neg) 92 ret double %r 93} 94 95define double @sin_unary_negated_arg(double %x) { 96; ANY-LABEL: @sin_unary_negated_arg( 97; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]]) 98; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] 99; ANY-NEXT: ret double [[TMP2]] 100; 101 %neg = fneg double %x 102 %r = call double @sin(double %neg) 103 ret double %r 104} 105 106define float @sinf_negated_arg(float %x) { 107; ANY-LABEL: @sinf_negated_arg( 108; ANY-NEXT: [[TMP1:%.*]] = call float @sinf(float [[X:%.*]]) 109; ANY-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] 110; ANY-NEXT: ret float [[TMP2]] 111; 112 %neg = fsub float -0.0, %x 113 %r = call float @sinf(float %neg) 114 ret float %r 115} 116 117define float @sinf_unary_negated_arg(float %x) { 118; ANY-LABEL: @sinf_unary_negated_arg( 119; ANY-NEXT: [[TMP1:%.*]] = call float @sinf(float [[X:%.*]]) 120; ANY-NEXT: [[TMP2:%.*]] = fneg float [[TMP1]] 121; ANY-NEXT: ret float [[TMP2]] 122; 123 %neg = fneg float %x 124 %r = call float @sinf(float %neg) 125 ret float %r 126} 127 128define float @sinf_negated_arg_FMF(float %x) { 129; ANY-LABEL: @sinf_negated_arg_FMF( 130; ANY-NEXT: [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]]) 131; ANY-NEXT: [[TMP2:%.*]] = fneg nnan afn float [[TMP1]] 132; ANY-NEXT: ret float [[TMP2]] 133; 134 %neg = fsub ninf float -0.0, %x 135 %r = call afn nnan float @sinf(float %neg) 136 ret float %r 137} 138 139define float @sinf_unary_negated_arg_FMF(float %x) { 140; ANY-LABEL: @sinf_unary_negated_arg_FMF( 141; ANY-NEXT: [[TMP1:%.*]] = call nnan afn float @sinf(float [[X:%.*]]) 142; ANY-NEXT: [[TMP2:%.*]] = fneg nnan afn float [[TMP1]] 143; ANY-NEXT: ret float [[TMP2]] 144; 145 %neg = fneg ninf float %x 146 %r = call afn nnan float @sinf(float %neg) 147 ret float %r 148} 149 150declare void @use(double) 151 152define double @sin_negated_arg_extra_use(double %x) { 153; ANY-LABEL: @sin_negated_arg_extra_use( 154; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]] 155; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]]) 156; ANY-NEXT: call void @use(double [[NEG]]) 157; ANY-NEXT: ret double [[R]] 158; 159 %neg = fsub double -0.0, %x 160 %r = call double @sin(double %neg) 161 call void @use(double %neg) 162 ret double %r 163} 164 165define double @sin_unary_negated_arg_extra_use(double %x) { 166; ANY-LABEL: @sin_unary_negated_arg_extra_use( 167; ANY-NEXT: [[NEG:%.*]] = fneg double [[X:%.*]] 168; ANY-NEXT: [[R:%.*]] = call double @sin(double [[NEG]]) 169; ANY-NEXT: call void @use(double [[NEG]]) 170; ANY-NEXT: ret double [[R]] 171; 172 %neg = fneg double %x 173 %r = call double @sin(double %neg) 174 call void @use(double %neg) 175 ret double %r 176} 177 178; -sin(-x) --> sin(x) 179; PR38458: https://bugs.llvm.org/show_bug.cgi?id=38458 180 181define double @neg_sin_negated_arg(double %x) { 182; ANY-LABEL: @neg_sin_negated_arg( 183; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]]) 184; ANY-NEXT: ret double [[TMP1]] 185; 186 %neg = fsub double -0.0, %x 187 %r = call double @sin(double %neg) 188 %rn = fsub double -0.0, %r 189 ret double %rn 190} 191 192define double @unary_neg_sin_unary_negated_arg(double %x) { 193; ANY-LABEL: @unary_neg_sin_unary_negated_arg( 194; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]]) 195; ANY-NEXT: ret double [[TMP1]] 196; 197 %neg = fneg double %x 198 %r = call double @sin(double %neg) 199 %rn = fneg double %r 200 ret double %rn 201} 202 203define double @neg_sin_unary_negated_arg(double %x) { 204; ANY-LABEL: @neg_sin_unary_negated_arg( 205; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]]) 206; ANY-NEXT: ret double [[TMP1]] 207; 208 %neg = fsub double -0.0, %x 209 %r = call double @sin(double %neg) 210 %rn = fneg double %r 211 ret double %rn 212} 213 214define double @unary_neg_sin_negated_arg(double %x) { 215; ANY-LABEL: @unary_neg_sin_negated_arg( 216; ANY-NEXT: [[TMP1:%.*]] = call double @sin(double [[X:%.*]]) 217; ANY-NEXT: ret double [[TMP1]] 218; 219 %neg = fneg double %x 220 %r = call double @sin(double %neg) 221 %rn = fsub double -0.0, %r 222 ret double %rn 223} 224 225; tan(-x) -> -tan(x); 226 227define double @tan_negated_arg(double %x) { 228; ANY-LABEL: @tan_negated_arg( 229; ANY-NEXT: [[TMP1:%.*]] = call double @tan(double [[X:%.*]]) 230; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] 231; ANY-NEXT: ret double [[TMP2]] 232; 233 %neg = fsub double -0.0, %x 234 %r = call double @tan(double %neg) 235 ret double %r 236} 237 238define double @tan_unary_negated_arg(double %x) { 239; ANY-LABEL: @tan_unary_negated_arg( 240; ANY-NEXT: [[TMP1:%.*]] = call double @tan(double [[X:%.*]]) 241; ANY-NEXT: [[TMP2:%.*]] = fneg double [[TMP1]] 242; ANY-NEXT: ret double [[TMP2]] 243; 244 %neg = fneg double %x 245 %r = call double @tan(double %neg) 246 ret double %r 247} 248 249; tanl(-x) -> -tanl(x); 250 251define fp128 @tanl_negated_arg(fp128 %x) { 252; ANY-LABEL: @tanl_negated_arg( 253; ANY-NEXT: [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]]) 254; ANY-NEXT: [[TMP2:%.*]] = fneg fp128 [[TMP1]] 255; ANY-NEXT: ret fp128 [[TMP2]] 256; 257 %neg = fsub fp128 0xL00000000000000008000000000000000, %x 258 %r = call fp128 @tanl(fp128 %neg) 259 ret fp128 %r 260} 261 262define fp128 @tanl_unary_negated_arg(fp128 %x) { 263; ANY-LABEL: @tanl_unary_negated_arg( 264; ANY-NEXT: [[TMP1:%.*]] = call fp128 @tanl(fp128 [[X:%.*]]) 265; ANY-NEXT: [[TMP2:%.*]] = fneg fp128 [[TMP1]] 266; ANY-NEXT: ret fp128 [[TMP2]] 267; 268 %neg = fneg fp128 %x 269 %r = call fp128 @tanl(fp128 %neg) 270 ret fp128 %r 271} 272 273define float @negated_and_shrinkable_libcall(float %f) { 274; NO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall( 275; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double 276; NO-FLOAT-SHRINK-NEXT: [[COS1:%.*]] = call double @cos(double [[CONV1]]) 277; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS1]] to float 278; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]] 279; 280; DO-FLOAT-SHRINK-LABEL: @negated_and_shrinkable_libcall( 281; DO-FLOAT-SHRINK-NEXT: [[COSF:%.*]] = call float @cosf(float [[F:%.*]]) 282; DO-FLOAT-SHRINK-NEXT: ret float [[COSF]] 283; 284 %conv1 = fpext float %f to double 285 %neg = fsub double -0.0, %conv1 286 %cos = call double @cos(double %neg) 287 %conv2 = fptrunc double %cos to float 288 ret float %conv2 289} 290 291define float @unary_negated_and_shrinkable_libcall(float %f) { 292; NO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall( 293; NO-FLOAT-SHRINK-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double 294; NO-FLOAT-SHRINK-NEXT: [[COS1:%.*]] = call double @cos(double [[CONV1]]) 295; NO-FLOAT-SHRINK-NEXT: [[CONV2:%.*]] = fptrunc double [[COS1]] to float 296; NO-FLOAT-SHRINK-NEXT: ret float [[CONV2]] 297; 298; DO-FLOAT-SHRINK-LABEL: @unary_negated_and_shrinkable_libcall( 299; DO-FLOAT-SHRINK-NEXT: [[COSF:%.*]] = call float @cosf(float [[F:%.*]]) 300; DO-FLOAT-SHRINK-NEXT: ret float [[COSF]] 301; 302 %conv1 = fpext float %f to double 303 %neg = fneg double %conv1 304 %cos = call double @cos(double %neg) 305 %conv2 = fptrunc double %cos to float 306 ret float %conv2 307} 308 309; TODO: It was ok to shrink the libcall, so the intrinsic should shrink too? 310 311define float @negated_and_shrinkable_intrinsic(float %f) { 312; ANY-LABEL: @negated_and_shrinkable_intrinsic( 313; ANY-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double 314; ANY-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]]) 315; ANY-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float 316; ANY-NEXT: ret float [[CONV2]] 317; 318 %conv1 = fpext float %f to double 319 %neg = fsub double -0.0, %conv1 320 %cos = call double @llvm.cos.f64(double %neg) 321 %conv2 = fptrunc double %cos to float 322 ret float %conv2 323} 324 325define float @unary_negated_and_shrinkable_intrinsic(float %f) { 326; ANY-LABEL: @unary_negated_and_shrinkable_intrinsic( 327; ANY-NEXT: [[CONV1:%.*]] = fpext float [[F:%.*]] to double 328; ANY-NEXT: [[COS:%.*]] = call double @llvm.cos.f64(double [[CONV1]]) 329; ANY-NEXT: [[CONV2:%.*]] = fptrunc double [[COS]] to float 330; ANY-NEXT: ret float [[CONV2]] 331; 332 %conv1 = fpext float %f to double 333 %neg = fneg double %conv1 334 %cos = call double @llvm.cos.f64(double %neg) 335 %conv2 = fptrunc double %cos to float 336 ret float %conv2 337} 338