1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4define float @test_inf_const(float %f) { 5; CHECK-LABEL: define float @test_inf_const( 6; CHECK-SAME: float [[F:%.*]]) { 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[ABS:%.*]] = tail call float @llvm.fabs.f32(float [[F]]) 9; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq float [[ABS]], 0x7FF0000000000000 10; CHECK-NEXT: br i1 [[ISINF]], label [[RETURN:%.*]], label [[IF_END:%.*]] 11; CHECK: if.end: 12; CHECK-NEXT: [[CALL:%.*]] = frem nnan float [[F]], 2.000000e+00 13; CHECK-NEXT: ret float [[CALL]] 14; CHECK: return: 15; CHECK-NEXT: ret float 0.000000e+00 16; 17entry: 18 %abs = tail call float @llvm.fabs.f32(float %f) 19 %isinf = fcmp oeq float %abs, 0x7FF0000000000000 20 br i1 %isinf, label %return, label %if.end 21 22if.end: 23 %call = tail call float @fmodf(float %f, float 2.0) 24 ret float %call 25 26return: 27 ret float 0.0 28} 29 30define float @test_const_zero(float %f) { 31; CHECK-LABEL: define float @test_const_zero( 32; CHECK-SAME: float [[F:%.*]]) { 33; CHECK-NEXT: entry: 34; CHECK-NEXT: [[ISZERO:%.*]] = fcmp oeq float [[F]], 0.000000e+00 35; CHECK-NEXT: br i1 [[ISZERO]], label [[RETURN:%.*]], label [[IF_END:%.*]] 36; CHECK: if.end: 37; CHECK-NEXT: [[CALL:%.*]] = frem nnan float 2.000000e+00, [[F]] 38; CHECK-NEXT: ret float [[CALL]] 39; CHECK: return: 40; CHECK-NEXT: ret float 0.000000e+00 41; 42entry: 43 %iszero = fcmp oeq float %f, 0.0 44 br i1 %iszero, label %return, label %if.end 45 46if.end: 47 %call = tail call float @fmodf(float 2.0, float %f) 48 ret float %call 49 50return: 51 ret float 0.0 52} 53 54define float @test_unknown_const(float %f) { 55; CHECK-LABEL: define float @test_unknown_const( 56; CHECK-SAME: float [[F:%.*]]) { 57; CHECK-NEXT: entry: 58; CHECK-NEXT: [[CALL:%.*]] = tail call float @fmodf(float [[F]], float 2.000000e+00) 59; CHECK-NEXT: ret float [[CALL]] 60; 61entry: 62 %call = tail call float @fmodf(float %f, float 2.000000e+00) 63 ret float %call 64} 65 66define float @test_noinf_nozero(float nofpclass(inf) %f, float nofpclass(zero) %g) { 67; CHECK-LABEL: define float @test_noinf_nozero( 68; CHECK-SAME: float nofpclass(inf) [[F:%.*]], float nofpclass(zero) [[G:%.*]]) { 69; CHECK-NEXT: entry: 70; CHECK-NEXT: [[CALL:%.*]] = frem nnan float [[F]], [[G]] 71; CHECK-NEXT: ret float [[CALL]] 72; 73entry: 74 %call = tail call float @fmodf(float %f, float %g) 75 ret float %call 76} 77 78define double @test_double(double nofpclass(inf) %f, double nofpclass(zero) %g) { 79; CHECK-LABEL: define double @test_double( 80; CHECK-SAME: double nofpclass(inf) [[F:%.*]], double nofpclass(zero) [[G:%.*]]) { 81; CHECK-NEXT: entry: 82; CHECK-NEXT: [[CALL:%.*]] = frem nnan double [[F]], [[G]] 83; CHECK-NEXT: ret double [[CALL]] 84; 85entry: 86 %call = tail call double @fmod(double %f, double %g) 87 ret double %call 88} 89 90define fp128 @test_fp128(fp128 nofpclass(inf) %f, fp128 nofpclass(zero) %g) { 91; CHECK-LABEL: define fp128 @test_fp128( 92; CHECK-SAME: fp128 nofpclass(inf) [[F:%.*]], fp128 nofpclass(zero) [[G:%.*]]) { 93; CHECK-NEXT: entry: 94; CHECK-NEXT: [[CALL:%.*]] = frem nnan fp128 [[F]], [[G]] 95; CHECK-NEXT: ret fp128 [[CALL]] 96; 97entry: 98 %call = tail call fp128 @fmodl(fp128 %f, fp128 %g) 99 ret fp128 %call 100} 101 102define float @test_noinf_nozero_dazpreservesign(float nofpclass(inf) %f, float nofpclass(zero) %g) "denormal-fp-math"="preserve-sign,preserve-sign" { 103; CHECK-LABEL: define float @test_noinf_nozero_dazpreservesign( 104; CHECK-SAME: float nofpclass(inf) [[F:%.*]], float nofpclass(zero) [[G:%.*]]) #[[ATTR0:[0-9]+]] { 105; CHECK-NEXT: entry: 106; CHECK-NEXT: [[CALL:%.*]] = tail call float @fmodf(float [[F]], float [[G]]) 107; CHECK-NEXT: ret float [[CALL]] 108; 109entry: 110 %call = tail call float @fmodf(float %f, float %g) 111 ret float %call 112} 113 114define float @test_noinf_nozero_dazdynamic(float nofpclass(inf) %f, float nofpclass(zero) %g) "denormal-fp-math"="dynamic,dynamic" { 115; CHECK-LABEL: define float @test_noinf_nozero_dazdynamic( 116; CHECK-SAME: float nofpclass(inf) [[F:%.*]], float nofpclass(zero) [[G:%.*]]) #[[ATTR1:[0-9]+]] { 117; CHECK-NEXT: entry: 118; CHECK-NEXT: [[CALL:%.*]] = tail call float @fmodf(float [[F]], float [[G]]) 119; CHECK-NEXT: ret float [[CALL]] 120; 121entry: 122 %call = tail call float @fmodf(float %f, float %g) 123 ret float %call 124} 125 126define float @test_nnan(float %f, float %g) { 127; CHECK-LABEL: define float @test_nnan( 128; CHECK-SAME: float [[F:%.*]], float [[G:%.*]]) { 129; CHECK-NEXT: entry: 130; CHECK-NEXT: [[CALL:%.*]] = frem nnan float [[F]], [[G]] 131; CHECK-NEXT: ret float [[CALL]] 132; 133entry: 134 %call = tail call nnan float @fmodf(float %f, float %g) 135 ret float %call 136} 137 138declare float @fmodf(float, float) 139declare double @fmod(double, double) 140declare fp128 @fmodl(fp128, fp128) 141