1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -instcombine -S < %s | FileCheck %s 3 4declare double @llvm.fabs.f64(double) 5declare float @llvm.fabs.f32(float) 6declare <4 x double> @llvm.fabs.v4f64(<4 x double>) 7declare void @use(double) 8 9declare double @llvm.copysign.f64(double, double) 10declare float @llvm.copysign.f32(float, float) 11 12define double @fabs_copysign(double %x) { 13; CHECK-LABEL: @fabs_copysign( 14; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]]) 15; CHECK-NEXT: ret double [[TMP1]] 16; 17 %f = tail call double @llvm.fabs.f64(double %x) 18 %div = fdiv nnan ninf double %x, %f 19 ret double %div 20} 21 22define double @fabs_copysign_commuted(double %x) { 23; CHECK-LABEL: @fabs_copysign_commuted( 24; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf double @llvm.copysign.f64(double 1.000000e+00, double [[X:%.*]]) 25; CHECK-NEXT: ret double [[TMP1]] 26; 27 %f = tail call double @llvm.fabs.f64(double %x) 28 %div = fdiv nnan ninf double %f, %x 29 ret double %div 30} 31 32define <4 x double> @fabs_copysign_vec(<4 x double> %x) { 33; CHECK-LABEL: @fabs_copysign_vec( 34; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf <4 x double> @llvm.copysign.v4f64(<4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, <4 x double> [[X:%.*]]) 35; CHECK-NEXT: ret <4 x double> [[TMP1]] 36; 37 %f = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x) 38 %div = fdiv nnan ninf <4 x double> %x, %f 39 ret <4 x double> %div 40} 41 42define <4 x double> @fabs_copysign_vec_commuted(<4 x double> %x) { 43; CHECK-LABEL: @fabs_copysign_vec_commuted( 44; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf <4 x double> @llvm.copysign.v4f64(<4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, <4 x double> [[X:%.*]]) 45; CHECK-NEXT: ret <4 x double> [[TMP1]] 46; 47 %f = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x) 48 %div = fdiv nnan ninf <4 x double> %f, %x 49 ret <4 x double> %div 50} 51 52define float @fabs_copysignf(float %x) { 53; CHECK-LABEL: @fabs_copysignf( 54; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]]) 55; CHECK-NEXT: ret float [[TMP1]] 56; 57 %f = tail call float @llvm.fabs.f32(float %x) 58 %div = fdiv nnan ninf float %x, %f 59 ret float %div 60} 61 62define double @fabs_copysign_use(double %x) { 63; CHECK-LABEL: @fabs_copysign_use( 64; CHECK-NEXT: [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) 65; CHECK-NEXT: call void @use(double [[F]]) 66; CHECK-NEXT: [[TMP1:%.*]] = call nnan ninf double @llvm.copysign.f64(double 1.000000e+00, double [[X]]) 67; CHECK-NEXT: ret double [[TMP1]] 68; 69 %f = tail call double @llvm.fabs.f64(double %x) 70 call void @use(double %f) 71 %div = fdiv nnan ninf double %x, %f 72 ret double %div 73} 74 75; Negative tests 76 77define double @fabs_copysign_mismatch(double %x, double %y) { 78; CHECK-LABEL: @fabs_copysign_mismatch( 79; CHECK-NEXT: [[F:%.*]] = tail call double @llvm.fabs.f64(double [[Y:%.*]]) 80; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[F]] 81; CHECK-NEXT: ret double [[DIV]] 82; 83 %f = tail call double @llvm.fabs.f64(double %y) 84 %div = fdiv double %x, %f 85 ret double %div 86} 87 88define double @fabs_copysign_commuted_mismatch(double %x, double %y) { 89; CHECK-LABEL: @fabs_copysign_commuted_mismatch( 90; CHECK-NEXT: [[F:%.*]] = tail call double @llvm.fabs.f64(double [[Y:%.*]]) 91; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[F]], [[X:%.*]] 92; CHECK-NEXT: ret double [[DIV]] 93; 94 %f = tail call double @llvm.fabs.f64(double %y) 95 %div = fdiv double %f, %x 96 ret double %div 97} 98 99define double @fabs_copysign_no_nnan(double %x) { 100; CHECK-LABEL: @fabs_copysign_no_nnan( 101; CHECK-NEXT: [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) 102; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf double [[X]], [[F]] 103; CHECK-NEXT: ret double [[DIV]] 104; 105 %f = tail call double @llvm.fabs.f64(double %x) 106 %div = fdiv ninf double %x, %f 107 ret double %div 108} 109 110define double @fabs_copysign_no_ninf(double %x) { 111; CHECK-LABEL: @fabs_copysign_no_ninf( 112; CHECK-NEXT: [[F:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]]) 113; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan double [[X]], [[F]] 114; CHECK-NEXT: ret double [[DIV]] 115; 116 %f = tail call double @llvm.fabs.f64(double %x) 117 %div = fdiv nnan double %x, %f 118 ret double %div 119} 120