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
4 declare float @sqrtf(float)
5 declare double @sqrt(double)
6 declare fp128 @sqrtl(fp128)
7 declare float @llvm.fabs.f32(float)
8 declare void @llvm.assume(i1 noundef)
10 ; "nnan" implies no setting of errno and the target can lower this to an
11 ; instruction, so transform to an intrinsic.
13 define 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]]
18 %sqrt = call nnan float @sqrtf(float %x)
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.
25 define 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]]
30 %sqrt = tail call nnan ninf double @sqrt(double %x)
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.
37 define 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]]
42 %sqrt = call nnan fp128 @sqrtl(fp128 %x)
46 ; Don't alter a no-builtin libcall.
48 define 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]]
53 %sqrt = call nnan float @sqrtf(float %x) nobuiltin
57 define 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]]
63 %x2 = fmul float %x, %x
64 %sqrt = call float @sqrtf(float %x2)
68 define 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]]
74 %a = call float @llvm.fabs.f32(float %x)
75 %sqrt = call float @sqrtf(float %a)
79 define 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]]
86 %is.pos = fcmp oge float %x, -0.0
87 call void @llvm.assume(i1 %is.pos)
88 %sqrt = call float @sqrtf(float %x)