379 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64 | FileCheck %s --check-prefixes=CHECK,CHECK-NOFULLFP163; RUN: llc < %s -mtriple=aarch64 --enable-no-nans-fp-math | FileCheck %s --check-prefixes=CHECK,CHECK-NONANS4; RUN: llc < %s -mtriple=aarch64 -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FULLFP165 6define <1 x float> @dup_v1i32_oeq(float %a, float %b) {7; CHECK-LABEL: dup_v1i32_oeq:8; CHECK: // %bb.0: // %entry9; CHECK-NEXT: fcmeq s0, s0, s110; CHECK-NEXT: ret11entry:12 %0 = fcmp oeq float %a, %b13 %vcmpd.i = sext i1 %0 to i3214 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 015 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>16 ret <1 x float> %117}18 19define <1 x float> @dup_v1i32_ogt(float %a, float %b) {20; CHECK-LABEL: dup_v1i32_ogt:21; CHECK: // %bb.0: // %entry22; CHECK-NEXT: fcmgt s0, s0, s123; CHECK-NEXT: ret24entry:25 %0 = fcmp ogt float %a, %b26 %vcmpd.i = sext i1 %0 to i3227 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 028 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>29 ret <1 x float> %130}31 32define <1 x float> @dup_v1i32_oge(float %a, float %b) {33; CHECK-LABEL: dup_v1i32_oge:34; CHECK: // %bb.0: // %entry35; CHECK-NEXT: fcmge s0, s0, s136; CHECK-NEXT: ret37entry:38 %0 = fcmp oge float %a, %b39 %vcmpd.i = sext i1 %0 to i3240 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 041 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>42 ret <1 x float> %143}44 45define <1 x float> @dup_v1i32_olt(float %a, float %b) {46; CHECK-LABEL: dup_v1i32_olt:47; CHECK: // %bb.0: // %entry48; CHECK-NEXT: fcmgt s0, s1, s049; CHECK-NEXT: ret50entry:51 %0 = fcmp olt float %a, %b52 %vcmpd.i = sext i1 %0 to i3253 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 054 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>55 ret <1 x float> %156}57 58define <1 x float> @dup_v1i32_ole(float %a, float %b) {59; CHECK-LABEL: dup_v1i32_ole:60; CHECK: // %bb.0: // %entry61; CHECK-NEXT: fcmge s0, s1, s062; CHECK-NEXT: ret63entry:64 %0 = fcmp ole float %a, %b65 %vcmpd.i = sext i1 %0 to i3266 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 067 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>68 ret <1 x float> %169}70 71define <1 x float> @dup_v1i32_one(float %a, float %b) {72; CHECK-NOFULLFP16-LABEL: dup_v1i32_one:73; CHECK-NOFULLFP16: // %bb.0: // %entry74; CHECK-NOFULLFP16-NEXT: fcmgt s2, s0, s175; CHECK-NOFULLFP16-NEXT: fcmgt s0, s1, s076; CHECK-NOFULLFP16-NEXT: orr v0.16b, v0.16b, v2.16b77; CHECK-NOFULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q078; CHECK-NOFULLFP16-NEXT: ret79;80; CHECK-NONANS-LABEL: dup_v1i32_one:81; CHECK-NONANS: // %bb.0: // %entry82; CHECK-NONANS-NEXT: fcmeq s0, s0, s183; CHECK-NONANS-NEXT: mvn v0.8b, v0.8b84; CHECK-NONANS-NEXT: ret85;86; CHECK-FULLFP16-LABEL: dup_v1i32_one:87; CHECK-FULLFP16: // %bb.0: // %entry88; CHECK-FULLFP16-NEXT: fcmgt s2, s0, s189; CHECK-FULLFP16-NEXT: fcmgt s0, s1, s090; CHECK-FULLFP16-NEXT: orr v0.16b, v0.16b, v2.16b91; CHECK-FULLFP16-NEXT: // kill: def $d0 killed $d0 killed $q092; CHECK-FULLFP16-NEXT: ret93entry:94 %0 = fcmp one float %a, %b95 %vcmpd.i = sext i1 %0 to i3296 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 097 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>98 ret <1 x float> %199}100 101define <1 x float> @dup_v1i32_ord(float %a, float %b) {102; CHECK-LABEL: dup_v1i32_ord:103; CHECK: // %bb.0: // %entry104; CHECK-NEXT: fcmge s2, s0, s1105; CHECK-NEXT: fcmgt s0, s1, s0106; CHECK-NEXT: orr v0.16b, v0.16b, v2.16b107; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0108; CHECK-NEXT: ret109entry:110 %0 = fcmp ord float %a, %b111 %vcmpd.i = sext i1 %0 to i32112 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0113 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>114 ret <1 x float> %1115}116 117define <1 x float> @dup_v1i32_ueq(float %a, float %b) {118; CHECK-NOFULLFP16-LABEL: dup_v1i32_ueq:119; CHECK-NOFULLFP16: // %bb.0: // %entry120; CHECK-NOFULLFP16-NEXT: fcmgt s2, s0, s1121; CHECK-NOFULLFP16-NEXT: fcmgt s0, s1, s0122; CHECK-NOFULLFP16-NEXT: orr v0.16b, v0.16b, v2.16b123; CHECK-NOFULLFP16-NEXT: mvn v0.8b, v0.8b124; CHECK-NOFULLFP16-NEXT: ret125;126; CHECK-NONANS-LABEL: dup_v1i32_ueq:127; CHECK-NONANS: // %bb.0: // %entry128; CHECK-NONANS-NEXT: fcmeq s0, s0, s1129; CHECK-NONANS-NEXT: ret130;131; CHECK-FULLFP16-LABEL: dup_v1i32_ueq:132; CHECK-FULLFP16: // %bb.0: // %entry133; CHECK-FULLFP16-NEXT: fcmgt s2, s0, s1134; CHECK-FULLFP16-NEXT: fcmgt s0, s1, s0135; CHECK-FULLFP16-NEXT: orr v0.16b, v0.16b, v2.16b136; CHECK-FULLFP16-NEXT: mvn v0.8b, v0.8b137; CHECK-FULLFP16-NEXT: ret138entry:139 %0 = fcmp ueq float %a, %b140 %vcmpd.i = sext i1 %0 to i32141 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0142 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>143 ret <1 x float> %1144}145 146define <1 x float> @dup_v1i32_ugt(float %a, float %b) {147; CHECK-NOFULLFP16-LABEL: dup_v1i32_ugt:148; CHECK-NOFULLFP16: // %bb.0: // %entry149; CHECK-NOFULLFP16-NEXT: fcmge s0, s1, s0150; CHECK-NOFULLFP16-NEXT: mvn v0.8b, v0.8b151; CHECK-NOFULLFP16-NEXT: ret152;153; CHECK-NONANS-LABEL: dup_v1i32_ugt:154; CHECK-NONANS: // %bb.0: // %entry155; CHECK-NONANS-NEXT: fcmgt s0, s0, s1156; CHECK-NONANS-NEXT: ret157;158; CHECK-FULLFP16-LABEL: dup_v1i32_ugt:159; CHECK-FULLFP16: // %bb.0: // %entry160; CHECK-FULLFP16-NEXT: fcmge s0, s1, s0161; CHECK-FULLFP16-NEXT: mvn v0.8b, v0.8b162; CHECK-FULLFP16-NEXT: ret163entry:164 %0 = fcmp ugt float %a, %b165 %vcmpd.i = sext i1 %0 to i32166 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0167 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>168 ret <1 x float> %1169}170 171define <1 x float> @dup_v1i32_uge(float %a, float %b) {172; CHECK-NOFULLFP16-LABEL: dup_v1i32_uge:173; CHECK-NOFULLFP16: // %bb.0: // %entry174; CHECK-NOFULLFP16-NEXT: fcmgt s0, s1, s0175; CHECK-NOFULLFP16-NEXT: mvn v0.8b, v0.8b176; CHECK-NOFULLFP16-NEXT: ret177;178; CHECK-NONANS-LABEL: dup_v1i32_uge:179; CHECK-NONANS: // %bb.0: // %entry180; CHECK-NONANS-NEXT: fcmge s0, s0, s1181; CHECK-NONANS-NEXT: ret182;183; CHECK-FULLFP16-LABEL: dup_v1i32_uge:184; CHECK-FULLFP16: // %bb.0: // %entry185; CHECK-FULLFP16-NEXT: fcmgt s0, s1, s0186; CHECK-FULLFP16-NEXT: mvn v0.8b, v0.8b187; CHECK-FULLFP16-NEXT: ret188entry:189 %0 = fcmp uge float %a, %b190 %vcmpd.i = sext i1 %0 to i32191 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0192 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>193 ret <1 x float> %1194}195 196define <1 x float> @dup_v1i32_ult(float %a, float %b) {197; CHECK-NOFULLFP16-LABEL: dup_v1i32_ult:198; CHECK-NOFULLFP16: // %bb.0: // %entry199; CHECK-NOFULLFP16-NEXT: fcmge s0, s0, s1200; CHECK-NOFULLFP16-NEXT: mvn v0.8b, v0.8b201; CHECK-NOFULLFP16-NEXT: ret202;203; CHECK-NONANS-LABEL: dup_v1i32_ult:204; CHECK-NONANS: // %bb.0: // %entry205; CHECK-NONANS-NEXT: fcmgt s0, s1, s0206; CHECK-NONANS-NEXT: ret207;208; CHECK-FULLFP16-LABEL: dup_v1i32_ult:209; CHECK-FULLFP16: // %bb.0: // %entry210; CHECK-FULLFP16-NEXT: fcmge s0, s0, s1211; CHECK-FULLFP16-NEXT: mvn v0.8b, v0.8b212; CHECK-FULLFP16-NEXT: ret213entry:214 %0 = fcmp ult float %a, %b215 %vcmpd.i = sext i1 %0 to i32216 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0217 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>218 ret <1 x float> %1219}220 221define <1 x float> @dup_v1i32_ule(float %a, float %b) {222; CHECK-NOFULLFP16-LABEL: dup_v1i32_ule:223; CHECK-NOFULLFP16: // %bb.0: // %entry224; CHECK-NOFULLFP16-NEXT: fcmgt s0, s0, s1225; CHECK-NOFULLFP16-NEXT: mvn v0.8b, v0.8b226; CHECK-NOFULLFP16-NEXT: ret227;228; CHECK-NONANS-LABEL: dup_v1i32_ule:229; CHECK-NONANS: // %bb.0: // %entry230; CHECK-NONANS-NEXT: fcmge s0, s1, s0231; CHECK-NONANS-NEXT: ret232;233; CHECK-FULLFP16-LABEL: dup_v1i32_ule:234; CHECK-FULLFP16: // %bb.0: // %entry235; CHECK-FULLFP16-NEXT: fcmgt s0, s0, s1236; CHECK-FULLFP16-NEXT: mvn v0.8b, v0.8b237; CHECK-FULLFP16-NEXT: ret238entry:239 %0 = fcmp ule float %a, %b240 %vcmpd.i = sext i1 %0 to i32241 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0242 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>243 ret <1 x float> %1244}245 246define <1 x float> @dup_v1i32_une(float %a, float %b) {247; CHECK-LABEL: dup_v1i32_une:248; CHECK: // %bb.0: // %entry249; CHECK-NEXT: fcmeq s0, s0, s1250; CHECK-NEXT: mvn v0.8b, v0.8b251; CHECK-NEXT: ret252entry:253 %0 = fcmp une float %a, %b254 %vcmpd.i = sext i1 %0 to i32255 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0256 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>257 ret <1 x float> %1258}259 260define <1 x float> @dup_v1i32_uno(float %a, float %b) {261; CHECK-LABEL: dup_v1i32_uno:262; CHECK: // %bb.0: // %entry263; CHECK-NEXT: fcmge s2, s0, s1264; CHECK-NEXT: fcmgt s0, s1, s0265; CHECK-NEXT: orr v0.16b, v0.16b, v2.16b266; CHECK-NEXT: mvn v0.8b, v0.8b267; CHECK-NEXT: ret268entry:269 %0 = fcmp uno float %a, %b270 %vcmpd.i = sext i1 %0 to i32271 %vecinit.i = insertelement <1 x i32> poison, i32 %vcmpd.i, i64 0272 %1 = bitcast <1 x i32> %vecinit.i to <1 x float>273 ret <1 x float> %1274}275 276define <4 x float> @dup_v4i32(float %a, float %b) {277; CHECK-LABEL: dup_v4i32:278; CHECK: // %bb.0: // %entry279; CHECK-NEXT: fcmge s0, s0, s1280; CHECK-NEXT: dup v0.4s, v0.s[0]281; CHECK-NEXT: ret282entry:283 %0 = fcmp oge float %a, %b284 %vcmpd.i = sext i1 %0 to i32285 %vecinit.i = insertelement <4 x i32> poison, i32 %vcmpd.i, i64 0286 %1 = bitcast <4 x i32> %vecinit.i to <4 x float>287 %2 = shufflevector <4 x float> %1, <4 x float> poison, <4 x i32> zeroinitializer288 ret <4 x float> %2289}290 291define <4 x float> @dup_v4i32_reversed(float %a, float %b) {292; CHECK-LABEL: dup_v4i32_reversed:293; CHECK: // %bb.0: // %entry294; CHECK-NEXT: fcmgt s0, s1, s0295; CHECK-NEXT: dup v0.4s, v0.s[0]296; CHECK-NEXT: ret297entry:298 %0 = fcmp ogt float %b, %a299 %vcmpd.i = sext i1 %0 to i32300 %vecinit.i = insertelement <4 x i32> poison, i32 %vcmpd.i, i64 0301 %1 = bitcast <4 x i32> %vecinit.i to <4 x float>302 %2 = shufflevector <4 x float> %1, <4 x float> poison, <4 x i32> zeroinitializer303 ret <4 x float> %2304}305 306define <2 x double> @dup_v2i64(double %a, double %b) {307; CHECK-LABEL: dup_v2i64:308; CHECK: // %bb.0: // %entry309; CHECK-NEXT: fcmgt d0, d0, d1310; CHECK-NEXT: dup v0.2d, v0.d[0]311; CHECK-NEXT: ret312entry:313 %0 = fcmp ogt double %a, %b314 %vcmpd.i = sext i1 %0 to i64315 %vecinit.i = insertelement <2 x i64> poison, i64 %vcmpd.i, i64 0316 %1 = bitcast <2 x i64> %vecinit.i to <2 x double>317 %2 = shufflevector <2 x double> %1, <2 x double> poison, <2 x i32> zeroinitializer318 ret <2 x double> %2319}320 321define <8 x half> @dup_v8i16(half %a, half %b) {322; CHECK-NOFULLFP16-LABEL: dup_v8i16:323; CHECK-NOFULLFP16: // %bb.0: // %entry324; CHECK-NOFULLFP16-NEXT: fcvt s1, h1325; CHECK-NOFULLFP16-NEXT: fcvt s0, h0326; CHECK-NOFULLFP16-NEXT: fcmeq s0, s0, s1327; CHECK-NOFULLFP16-NEXT: ret328;329; CHECK-NONANS-LABEL: dup_v8i16:330; CHECK-NONANS: // %bb.0: // %entry331; CHECK-NONANS-NEXT: fcvt s1, h1332; CHECK-NONANS-NEXT: fcvt s0, h0333; CHECK-NONANS-NEXT: fcmeq s0, s0, s1334; CHECK-NONANS-NEXT: ret335;336; CHECK-FULLFP16-LABEL: dup_v8i16:337; CHECK-FULLFP16: // %bb.0: // %entry338; CHECK-FULLFP16-NEXT: fcmp h0, h1339; CHECK-FULLFP16-NEXT: csetm w8, eq340; CHECK-FULLFP16-NEXT: fmov s0, w8341; CHECK-FULLFP16-NEXT: ret342; FIXME: Could be replaced with fcmeq + dup but the type of the former is343; promoted to i32 during selection and then the optimization does not apply.344 345 entry:346 %0 = fcmp oeq half %a, %b347 %vcmpd.i = sext i1 %0 to i16348 %vecinit.i = insertelement <8 x i16> poison, i16 %vcmpd.i, i64 0349 %1 = bitcast <8 x i16> %vecinit.i to <8 x half>350 ret <8 x half> %1351}352 353; Check that a mask is not generated for non-vectorized users.354define i32 @mask_i32(float %a, float %b) {355; CHECK-LABEL: mask_i32:356; CHECK: // %bb.0: // %entry357; CHECK-NEXT: fcmp s0, s1358; CHECK-NEXT: csetm w0, eq359; CHECK-NEXT: ret360entry:361 %0 = fcmp oeq float %a, %b362 %vcmpd.i = sext i1 %0 to i32363 ret i32 %vcmpd.i364}365 366; Verify that a mask is not emitted when (allOnes, allZeros) are not the367; operands for the SELECT_CC.368define i32 @bool_i32(float %a, float %b) {369; CHECK-LABEL: bool_i32:370; CHECK: // %bb.0: // %entry371; CHECK-NEXT: fcmp s0, s1372; CHECK-NEXT: cset w0, eq373; CHECK-NEXT: ret374entry:375 %0 = fcmp oeq float %a, %b376 %vcmpd.i = zext i1 %0 to i32377 ret i32 %vcmpd.i378}379