1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -instcombine < %s | FileCheck %s 3 4declare float @llvm.fma.f32(float, float, float) #1 5declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) #1 6declare float @llvm.fmuladd.f32(float, float, float) #1 7declare float @llvm.fabs.f32(float) #1 8 9@external = external global i32 10 11define float @fma_fneg_x_fneg_y(float %x, float %y, float %z) { 12; CHECK-LABEL: @fma_fneg_x_fneg_y( 13; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) 14; CHECK-NEXT: ret float [[FMA]] 15; 16 %x.fneg = fsub float -0.0, %x 17 %y.fneg = fsub float -0.0, %y 18 %fma = call float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z) 19 ret float %fma 20} 21 22define <2 x float> @fma_fneg_x_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) { 23; CHECK-LABEL: @fma_fneg_x_fneg_y_vec( 24; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]]) 25; CHECK-NEXT: ret <2 x float> [[FMA]] 26; 27 %xn = fsub <2 x float> <float -0.0, float -0.0>, %x 28 %yn = fsub <2 x float> <float -0.0, float -0.0>, %y 29 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z) 30 ret <2 x float> %fma 31} 32 33define <2 x float> @fma_fneg_x_fneg_y_vec_undef(<2 x float> %x, <2 x float> %y, <2 x float> %z) { 34; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_undef( 35; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]]) 36; CHECK-NEXT: ret <2 x float> [[FMA]] 37; 38 %xn = fsub <2 x float> <float -0.0, float undef>, %x 39 %yn = fsub <2 x float> <float undef, float -0.0>, %y 40 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z) 41 ret <2 x float> %fma 42} 43 44define float @fma_fneg_x_fneg_y_fast(float %x, float %y, float %z) { 45; CHECK-LABEL: @fma_fneg_x_fneg_y_fast( 46; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) 47; CHECK-NEXT: ret float [[FMA]] 48; 49 %x.fneg = fsub float -0.0, %x 50 %y.fneg = fsub float -0.0, %y 51 %fma = call fast float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z) 52 ret float %fma 53} 54 55define float @fma_fneg_const_fneg_y(float %y, float %z) { 56; CHECK-LABEL: @fma_fneg_const_fneg_y( 57; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]]) 58; CHECK-NEXT: ret float [[FMA]] 59; 60 %y.fneg = fsub float -0.0, %y 61 %fma = call float @llvm.fma.f32(float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %y.fneg, float %z) 62 ret float %fma 63} 64 65define float @fma_fneg_x_fneg_const(float %x, float %z) { 66; CHECK-LABEL: @fma_fneg_x_fneg_const( 67; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]]) 68; CHECK-NEXT: ret float [[FMA]] 69; 70 %x.fneg = fsub float -0.0, %x 71 %fma = call float @llvm.fma.f32(float %x.fneg, float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %z) 72 ret float %fma 73} 74 75define float @fma_fabs_x_fabs_y(float %x, float %y, float %z) { 76; CHECK-LABEL: @fma_fabs_x_fabs_y( 77; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 78; CHECK-NEXT: [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]]) 79; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]]) 80; CHECK-NEXT: ret float [[FMA]] 81; 82 %x.fabs = call float @llvm.fabs.f32(float %x) 83 %y.fabs = call float @llvm.fabs.f32(float %y) 84 %fma = call float @llvm.fma.f32(float %x.fabs, float %y.fabs, float %z) 85 ret float %fma 86} 87 88define float @fma_fabs_x_fabs_x(float %x, float %z) { 89; CHECK-LABEL: @fma_fabs_x_fabs_x( 90; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]]) 91; CHECK-NEXT: ret float [[FMA]] 92; 93 %x.fabs = call float @llvm.fabs.f32(float %x) 94 %fma = call float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z) 95 ret float %fma 96} 97 98define float @fma_fabs_x_fabs_x_fast(float %x, float %z) { 99; CHECK-LABEL: @fma_fabs_x_fabs_x_fast( 100; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]]) 101; CHECK-NEXT: ret float [[FMA]] 102; 103 %x.fabs = call float @llvm.fabs.f32(float %x) 104 %fma = call fast float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z) 105 ret float %fma 106} 107 108define float @fmuladd_fneg_x_fneg_y(float %x, float %y, float %z) { 109; CHECK-LABEL: @fmuladd_fneg_x_fneg_y( 110; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]]) 111; CHECK-NEXT: ret float [[FMULADD]] 112; 113 %x.fneg = fsub float -0.0, %x 114 %y.fneg = fsub float -0.0, %y 115 %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z) 116 ret float %fmuladd 117} 118 119define float @fmuladd_fneg_x_fneg_y_fast(float %x, float %y, float %z) { 120; CHECK-LABEL: @fmuladd_fneg_x_fneg_y_fast( 121; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[Y:%.*]] 122; CHECK-NEXT: [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]] 123; CHECK-NEXT: ret float [[FMULADD]] 124; 125 %x.fneg = fsub float -0.0, %x 126 %y.fneg = fsub float -0.0, %y 127 %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z) 128 ret float %fmuladd 129} 130 131define float @fmuladd_fneg_const_fneg_y(float %y, float %z) { 132; CHECK-LABEL: @fmuladd_fneg_const_fneg_y( 133; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]]) 134; CHECK-NEXT: ret float [[FMULADD]] 135; 136 %y.fneg = fsub float -0.0, %y 137 %fmuladd = call float @llvm.fmuladd.f32(float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %y.fneg, float %z) 138 ret float %fmuladd 139} 140 141define float @fmuladd_fneg_x_fneg_const(float %x, float %z) { 142; CHECK-LABEL: @fmuladd_fneg_x_fneg_const( 143; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]]) 144; CHECK-NEXT: ret float [[FMULADD]] 145; 146 %x.fneg = fsub float -0.0, %x 147 %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %z) 148 ret float %fmuladd 149} 150 151define float @fmuladd_fabs_x_fabs_y(float %x, float %y, float %z) { 152; CHECK-LABEL: @fmuladd_fabs_x_fabs_y( 153; CHECK-NEXT: [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]]) 154; CHECK-NEXT: [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]]) 155; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]]) 156; CHECK-NEXT: ret float [[FMULADD]] 157; 158 %x.fabs = call float @llvm.fabs.f32(float %x) 159 %y.fabs = call float @llvm.fabs.f32(float %y) 160 %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %y.fabs, float %z) 161 ret float %fmuladd 162} 163 164define float @fmuladd_fabs_x_fabs_x(float %x, float %z) { 165; CHECK-LABEL: @fmuladd_fabs_x_fabs_x( 166; CHECK-NEXT: [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]]) 167; CHECK-NEXT: ret float [[FMULADD]] 168; 169 %x.fabs = call float @llvm.fabs.f32(float %x) 170 %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z) 171 ret float %fmuladd 172} 173 174define float @fmuladd_fabs_x_fabs_x_fast(float %x, float %z) { 175; CHECK-LABEL: @fmuladd_fabs_x_fabs_x_fast( 176; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[X]] 177; CHECK-NEXT: [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]] 178; CHECK-NEXT: ret float [[FMULADD]] 179; 180 %x.fabs = call float @llvm.fabs.f32(float %x) 181 %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z) 182 ret float %fmuladd 183} 184 185define float @fma_k_y_z(float %y, float %z) { 186; CHECK-LABEL: @fma_k_y_z( 187; CHECK-NEXT: [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]]) 188; CHECK-NEXT: ret float [[FMA]] 189; 190 %fma = call float @llvm.fma.f32(float 4.0, float %y, float %z) 191 ret float %fma 192} 193 194define float @fma_k_y_z_fast(float %y, float %z) { 195; CHECK-LABEL: @fma_k_y_z_fast( 196; CHECK-NEXT: [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]]) 197; CHECK-NEXT: ret float [[FMA]] 198; 199 %fma = call fast float @llvm.fma.f32(float 4.0, float %y, float %z) 200 ret float %fma 201} 202 203define float @fmuladd_k_y_z_fast(float %y, float %z) { 204; CHECK-LABEL: @fmuladd_k_y_z_fast( 205; CHECK-NEXT: [[TMP1:%.*]] = fmul fast float [[Y:%.*]], 4.000000e+00 206; CHECK-NEXT: [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]] 207; CHECK-NEXT: ret float [[FMULADD]] 208; 209 %fmuladd = call fast float @llvm.fmuladd.f32(float 4.0, float %y, float %z) 210 ret float %fmuladd 211} 212 213define float @fma_1_y_z(float %y, float %z) { 214; CHECK-LABEL: @fma_1_y_z( 215; CHECK-NEXT: [[FMA:%.*]] = fadd float [[Y:%.*]], [[Z:%.*]] 216; CHECK-NEXT: ret float [[FMA]] 217; 218 %fma = call float @llvm.fma.f32(float 1.0, float %y, float %z) 219 ret float %fma 220} 221 222define float @fma_x_1_z(float %x, float %z) { 223; CHECK-LABEL: @fma_x_1_z( 224; CHECK-NEXT: [[FMA:%.*]] = fadd float [[X:%.*]], [[Z:%.*]] 225; CHECK-NEXT: ret float [[FMA]] 226; 227 %fma = call float @llvm.fma.f32(float %x, float 1.0, float %z) 228 ret float %fma 229} 230 231define <2 x float> @fma_x_1_z_v2f32(<2 x float> %x, <2 x float> %z) { 232; CHECK-LABEL: @fma_x_1_z_v2f32( 233; CHECK-NEXT: [[FMA:%.*]] = fadd <2 x float> [[X:%.*]], [[Z:%.*]] 234; CHECK-NEXT: ret <2 x float> [[FMA]] 235; 236 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>, <2 x float> %z) 237 ret <2 x float> %fma 238} 239 240define <2 x float> @fma_x_1_2_z_v2f32(<2 x float> %x, <2 x float> %z) { 241; CHECK-LABEL: @fma_x_1_2_z_v2f32( 242; CHECK-NEXT: [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float> [[Z:%.*]]) 243; CHECK-NEXT: ret <2 x float> [[FMA]] 244; 245 %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 2.0>, <2 x float> %z) 246 ret <2 x float> %fma 247} 248 249define float @fma_x_1_z_fast(float %x, float %z) { 250; CHECK-LABEL: @fma_x_1_z_fast( 251; CHECK-NEXT: [[FMA:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]] 252; CHECK-NEXT: ret float [[FMA]] 253; 254 %fma = call fast float @llvm.fma.f32(float %x, float 1.0, float %z) 255 ret float %fma 256} 257 258define float @fma_1_1_z(float %z) { 259; CHECK-LABEL: @fma_1_1_z( 260; CHECK-NEXT: [[FMA:%.*]] = fadd float [[Z:%.*]], 1.000000e+00 261; CHECK-NEXT: ret float [[FMA]] 262; 263 %fma = call float @llvm.fma.f32(float 1.0, float 1.0, float %z) 264 ret float %fma 265} 266 267define float @fmuladd_x_1_z_fast(float %x, float %z) { 268; CHECK-LABEL: @fmuladd_x_1_z_fast( 269; CHECK-NEXT: [[FMULADD:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]] 270; CHECK-NEXT: ret float [[FMULADD]] 271; 272 %fmuladd = call fast float @llvm.fmuladd.f32(float %x, float 1.0, float %z) 273 ret float %fmuladd 274} 275 276attributes #0 = { nounwind } 277attributes #1 = { nounwind readnone } 278