1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define double @log_pow(double %x, double %y) { 5; CHECK-LABEL: @log_pow( 6; CHECK-NEXT: [[LOG1:%.*]] = call fast double @llvm.log.f64(double [[X:%.*]]) 7; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[Y:%.*]], [[LOG1]] 8; CHECK-NEXT: ret double [[MUL]] 9; 10 %pow = call fast double @pow(double %x, double %y) 11 %log = call fast double @log(double %pow) 12 ret double %log 13} 14 15define double @log_powi_const(double %x) { 16; CHECK-LABEL: @log_powi_const( 17; CHECK-NEXT: [[LOG1:%.*]] = call fast double @llvm.log.f64(double [[X:%.*]]) 18; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[LOG1]], -3.000000e+00 19; CHECK-NEXT: ret double [[MUL]] 20; 21 %pow = call fast double @llvm.powi.f64.i32(double %x, i32 -3) 22 %log = call fast double @log(double %pow) 23 ret double %log 24} 25 26define double @log_powi_nonconst(double %x, i32 %y) { 27; CHECK-LABEL: @log_powi_nonconst( 28; CHECK-NEXT: [[LOG1:%.*]] = call fast double @llvm.log.f64(double [[X:%.*]]) 29; CHECK-NEXT: [[CAST:%.*]] = sitofp i32 [[Y:%.*]] to double 30; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[LOG1]], [[CAST]] 31; CHECK-NEXT: ret double [[MUL]] 32; 33 %pow = call fast double @llvm.powi.f64.i32(double %x, i32 %y) 34 %log = call fast double @log(double %pow) 35 ret double %log 36} 37 38define double @logf64_powi_nonconst(double %x, i32 %y) { 39; CHECK-LABEL: @logf64_powi_nonconst( 40; CHECK-NEXT: [[LOG1:%.*]] = call fast double @llvm.log.f64(double [[X:%.*]]) 41; CHECK-NEXT: [[CAST:%.*]] = sitofp i32 [[Y:%.*]] to double 42; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[LOG1]], [[CAST]] 43; CHECK-NEXT: ret double [[MUL]] 44; 45 %pow = call fast double @llvm.powi.f64.i32(double %x, i32 %y) 46 %log = call fast double @llvm.log.f64(double %pow) 47 ret double %log 48} 49 50define float @logf_powfi_const(float %x) { 51; CHECK-LABEL: @logf_powfi_const( 52; CHECK-NEXT: [[LOG1:%.*]] = call fast float @llvm.log.f32(float [[X:%.*]]) 53; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[LOG1]], -3.000000e+00 54; CHECK-NEXT: ret float [[MUL]] 55; 56 %pow = call fast float @llvm.powi.f32.i32(float %x, i32 -3) 57 %log = call fast float @logf(float %pow) 58 ret float %log 59} 60 61define float @logf_powfi_nonconst(float %x, i32 %y) { 62; CHECK-LABEL: @logf_powfi_nonconst( 63; CHECK-NEXT: [[LOG1:%.*]] = call fast float @llvm.log.f32(float [[X:%.*]]) 64; CHECK-NEXT: [[CAST:%.*]] = sitofp i32 [[Y:%.*]] to float 65; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[LOG1]], [[CAST]] 66; CHECK-NEXT: ret float [[MUL]] 67; 68 %pow = call fast float @llvm.powi.f32.i32(float %x, i32 %y) 69 %log = call fast float @logf(float %pow) 70 ret float %log 71} 72 73define double @log_powi_not_fast(double %x, i32 %y) { 74; CHECK-LABEL: @log_powi_not_fast( 75; CHECK-NEXT: [[POW:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]]) 76; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[POW]]) 77; CHECK-NEXT: ret double [[LOG]] 78; 79 %pow = call double @llvm.powi.f64.i32(double %x, i32 %y) 80 %log = call fast double @log(double %pow) 81 ret double %log 82} 83 84define float @log10f_powf(float %x, float %y) { 85; CHECK-LABEL: @log10f_powf( 86; CHECK-NEXT: [[LOG1:%.*]] = call fast float @llvm.log10.f32(float [[X:%.*]]) 87; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[Y:%.*]], [[LOG1]] 88; CHECK-NEXT: ret float [[MUL]] 89; 90 %pow = call fast float @powf(float %x, float %y) 91 %log = call fast float @llvm.log10.f32(float %pow) 92 ret float %log 93} 94 95define <2 x double> @log2v_powv(<2 x double> %x, <2 x double> %y) { 96; CHECK-LABEL: @log2v_powv( 97; CHECK-NEXT: [[LOG1:%.*]] = call fast <2 x double> @llvm.log2.v2f64(<2 x double> [[X:%.*]]) 98; CHECK-NEXT: [[MUL:%.*]] = fmul fast <2 x double> [[Y:%.*]], [[LOG1]] 99; CHECK-NEXT: ret <2 x double> [[MUL]] 100; 101 %pow = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> %y) 102 %log = call fast <2 x double> @llvm.log2.v2f64(<2 x double> %pow) 103 ret <2 x double> %log 104} 105 106define double @log_pow_not_fast(double %x, double %y) { 107; CHECK-LABEL: @log_pow_not_fast( 108; CHECK-NEXT: [[POW:%.*]] = call double @pow(double [[X:%.*]], double [[Y:%.*]]) 109; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[POW]]) 110; CHECK-NEXT: ret double [[LOG]] 111; 112 %pow = call double @pow(double %x, double %y) 113 %log = call fast double @log(double %pow) 114 ret double %log 115} 116 117define float @function_pointer(ptr %fptr, float %p1) { 118; CHECK-LABEL: @function_pointer( 119; CHECK-NEXT: [[PTR:%.*]] = call float [[FPTR:%.*]]() 120; CHECK-NEXT: [[LOG:%.*]] = call float @logf(float [[PTR]]) 121; CHECK-NEXT: ret float [[LOG]] 122; 123 %ptr = call float %fptr() 124 %log = call float @logf(float %ptr) 125 ret float %log 126} 127 128define double @log10_exp(double %x) { 129; CHECK-LABEL: @log10_exp( 130; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[X:%.*]], 0x3FDBCB7B1526E50E 131; CHECK-NEXT: ret double [[MUL]] 132; 133 %exp = call fast double @exp(double %x) 134 %log = call fast double @log10(double %exp) 135 ret double %log 136} 137 138define <2 x float> @logv_exp2v(<2 x float> %x) { 139; CHECK-LABEL: @logv_exp2v( 140; CHECK-NEXT: [[MUL:%.*]] = fmul fast <2 x float> [[X:%.*]], splat (float 0x3FE62E4300000000) 141; CHECK-NEXT: ret <2 x float> [[MUL]] 142; 143 %exp = call fast <2 x float> @llvm.exp2.v2f32(<2 x float> %x) 144 %log = call fast <2 x float> @llvm.log.v2f32(<2 x float> %exp) 145 ret <2 x float> %log 146} 147 148define float @log2f_exp10f(float %x) { 149; CHECK-LABEL: @log2f_exp10f( 150; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[X:%.*]], 0x400A934F00000000 151; CHECK-NEXT: ret float [[MUL]] 152; 153 %exp = call fast float @exp10f(float %x) 154 %log = call fast float @log2f(float %exp) 155 ret float %log 156} 157 158define double @log_exp2_not_fast(double %x) { 159; CHECK-LABEL: @log_exp2_not_fast( 160; CHECK-NEXT: [[EXP:%.*]] = call double @exp2(double [[X:%.*]]) 161; CHECK-NEXT: [[LOG:%.*]] = call fast double @llvm.log.f64(double [[EXP]]) 162; CHECK-NEXT: ret double [[LOG]] 163; 164 %exp = call double @exp2(double %x) 165 %log = call fast double @log(double %exp) 166 ret double %log 167} 168 169define double @pr43617(double %d, i32 %i, ptr %f) { 170; CHECK-LABEL: @pr43617( 171; CHECK-NEXT: entry: 172; CHECK-NEXT: [[SUB:%.*]] = fneg double [[D:%.*]] 173; CHECK-NEXT: [[ICALL:%.*]] = tail call fast double [[F:%.*]](i32 [[I:%.*]]) 174; CHECK-NEXT: [[LOG:%.*]] = tail call fast double @llvm.log.f64(double [[ICALL]]) 175; CHECK-NEXT: [[MUL:%.*]] = fmul double [[LOG]], [[SUB]] 176; CHECK-NEXT: ret double [[MUL]] 177; 178entry: 179 %sub = fsub double -0.000000e+00, %d 180 %icall = tail call fast double %f(i32 %i) 181 %log = tail call fast double @llvm.log.f64(double %icall) 182 %mul = fmul double %log, %sub 183 ret double %mul 184} 185 186declare double @log(double) #0 187declare float @logf(float) #0 188declare double @llvm.log.f64(double) #0 189declare <2 x float> @llvm.log.v2f32(<2 x float>) 190declare float @log2f(float) #0 191declare <2 x double> @llvm.log2.v2f64(<2 x double>) 192declare double @log10(double) #0 193declare float @llvm.log10.f32(float) 194declare double @exp(double %x) #0 195declare double @exp2(double) #0 196declare float @exp10f(float) #0 197declare <2 x float> @llvm.exp2.v2f32(<2 x float>) 198declare double @pow(double, double) #0 199declare float @powf(float, float) #0 200declare float @llvm.powi.f32.i32(float, i32) #0 201declare double @llvm.powi.f64.i32(double, i32) #0 202declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) 203 204attributes #0 = { nounwind readnone } 205