1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=aggressive-instcombine -mtriple x86_64-- -S | FileCheck %s 3 4declare float @sqrtf(float) 5declare double @sqrt(double) 6declare fp128 @sqrtl(fp128) 7declare float @llvm.fabs.f32(float) 8declare void @llvm.assume(i1 noundef) 9 10; "nnan" implies no setting of errno and the target can lower this to an 11; instruction, so transform to an intrinsic. 12 13define float @sqrt_call_nnan_f32(float %x) { 14; CHECK-LABEL: @sqrt_call_nnan_f32( 15; CHECK-NEXT: [[SQRT1:%.*]] = call nnan float @llvm.sqrt.f32(float [[X:%.*]]) 16; CHECK-NEXT: ret float [[SQRT1]] 17; 18 %sqrt = call nnan float @sqrtf(float %x) 19 ret float %sqrt 20} 21 22; Verify that other FMF are propagated to the intrinsic call. 23; We don't care about propagating 'tail' because this is not going to be a lowered as a call. 24 25define double @sqrt_call_nnan_f64(double %x) { 26; CHECK-LABEL: @sqrt_call_nnan_f64( 27; CHECK-NEXT: [[SQRT1:%.*]] = call nnan ninf double @llvm.sqrt.f64(double [[X:%.*]]) 28; CHECK-NEXT: ret double [[SQRT1]] 29; 30 %sqrt = tail call nnan ninf double @sqrt(double %x) 31 ret double %sqrt 32} 33 34; We don't change this because it will be lowered to a call that could 35; theoretically still change errno and affect other accessors of errno. 36 37define fp128 @sqrt_call_nnan_f128(fp128 %x) { 38; CHECK-LABEL: @sqrt_call_nnan_f128( 39; CHECK-NEXT: [[SQRT:%.*]] = call nnan fp128 @sqrtl(fp128 [[X:%.*]]) 40; CHECK-NEXT: ret fp128 [[SQRT]] 41; 42 %sqrt = call nnan fp128 @sqrtl(fp128 %x) 43 ret fp128 %sqrt 44} 45 46; Don't alter a no-builtin libcall. 47 48define float @sqrt_call_nnan_f32_nobuiltin(float %x) { 49; CHECK-LABEL: @sqrt_call_nnan_f32_nobuiltin( 50; CHECK-NEXT: [[SQRT:%.*]] = call nnan float @sqrtf(float [[X:%.*]]) #[[ATTR2:[0-9]+]] 51; CHECK-NEXT: ret float [[SQRT]] 52; 53 %sqrt = call nnan float @sqrtf(float %x) nobuiltin 54 ret float %sqrt 55} 56 57define float @sqrt_call_f32_squared(float %x) { 58; CHECK-LABEL: @sqrt_call_f32_squared( 59; CHECK-NEXT: [[X2:%.*]] = fmul float [[X:%.*]], [[X]] 60; CHECK-NEXT: [[SQRT1:%.*]] = call float @llvm.sqrt.f32(float [[X2]]) 61; CHECK-NEXT: ret float [[SQRT1]] 62; 63 %x2 = fmul float %x, %x 64 %sqrt = call float @sqrtf(float %x2) 65 ret float %sqrt 66} 67 68define float @sqrt_call_f32_fabs(float %x) { 69; CHECK-LABEL: @sqrt_call_f32_fabs( 70; CHECK-NEXT: [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 71; CHECK-NEXT: [[SQRT1:%.*]] = call float @llvm.sqrt.f32(float [[A]]) 72; CHECK-NEXT: ret float [[SQRT1]] 73; 74 %a = call float @llvm.fabs.f32(float %x) 75 %sqrt = call float @sqrtf(float %a) 76 ret float %sqrt 77} 78 79define float @sqrt_call_f32_assume_oge_n0(float %x) { 80; CHECK-LABEL: @sqrt_call_f32_assume_oge_n0( 81; CHECK-NEXT: [[IS_POS:%.*]] = fcmp oge float [[X:%.*]], -0.000000e+00 82; CHECK-NEXT: call void @llvm.assume(i1 [[IS_POS]]) 83; CHECK-NEXT: [[SQRT1:%.*]] = call float @llvm.sqrt.f32(float [[X]]) 84; CHECK-NEXT: ret float [[SQRT1]] 85; 86 %is.pos = fcmp oge float %x, -0.0 87 call void @llvm.assume(i1 %is.pos) 88 %sqrt = call float @sqrtf(float %x) 89 ret float %sqrt 90} 91