233 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -mtriple=armv7-apple-darwin < %s -codegenprepare -S | FileCheck -check-prefix=NEON %s3; RUN: opt -mtriple=armv6-unknown-linux < %s -codegenprepare -S | FileCheck -check-prefix=NONEON %s4 5define <8 x i16> @sink_zext(<8 x i8> %a, <8 x i8> %b, i1 %c) {6; NEON-LABEL: @sink_zext(7; NEON-NEXT: entry:8; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]9; NEON: if.then:10; NEON-NEXT: [[TMP0:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>11; NEON-NEXT: [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>12; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]13; NEON-NEXT: ret <8 x i16> [[RES_1]]14; NEON: if.else:15; NEON-NEXT: [[TMP1:%.*]] = zext <8 x i8> [[A]] to <8 x i16>16; NEON-NEXT: [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>17; NEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]18; NEON-NEXT: ret <8 x i16> [[RES_2]]19;20; NONEON-LABEL: @sink_zext(21; NONEON-NEXT: entry:22; NONEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>23; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]24; NONEON: if.then:25; NONEON-NEXT: [[ZB_1:%.*]] = zext <8 x i8> [[B:%.*]] to <8 x i16>26; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]27; NONEON-NEXT: ret <8 x i16> [[RES_1]]28; NONEON: if.else:29; NONEON-NEXT: [[ZB_2:%.*]] = zext <8 x i8> [[B]] to <8 x i16>30; NONEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]31; NONEON-NEXT: ret <8 x i16> [[RES_2]]32;33entry:34 %za = zext <8 x i8> %a to <8 x i16>35 br i1 %c, label %if.then, label %if.else36 37if.then:38 %zb.1 = zext <8 x i8> %b to <8 x i16>39 %res.1 = add <8 x i16> %za, %zb.140 ret <8 x i16> %res.141 42if.else:43 %zb.2 = zext <8 x i8> %b to <8 x i16>44 %res.2 = sub <8 x i16> %za, %zb.245 ret <8 x i16> %res.246}47 48define <8 x i16> @sink_sext(<8 x i8> %a, <8 x i8> %b, i1 %c) {49; NEON-LABEL: @sink_sext(50; NEON-NEXT: entry:51; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]52; NEON: if.then:53; NEON-NEXT: [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>54; NEON-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>55; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]56; NEON-NEXT: ret <8 x i16> [[RES_1]]57; NEON: if.else:58; NEON-NEXT: [[TMP1:%.*]] = sext <8 x i8> [[A]] to <8 x i16>59; NEON-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>60; NEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[TMP1]], [[ZB_2]]61; NEON-NEXT: ret <8 x i16> [[RES_2]]62;63; NONEON-LABEL: @sink_sext(64; NONEON-NEXT: entry:65; NONEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>66; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]67; NONEON: if.then:68; NONEON-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>69; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[ZB_1]]70; NONEON-NEXT: ret <8 x i16> [[RES_1]]71; NONEON: if.else:72; NONEON-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>73; NONEON-NEXT: [[RES_2:%.*]] = sub <8 x i16> [[ZA]], [[ZB_2]]74; NONEON-NEXT: ret <8 x i16> [[RES_2]]75;76entry:77 %za = sext <8 x i8> %a to <8 x i16>78 br i1 %c, label %if.then, label %if.else79 80if.then:81 %zb.1 = sext <8 x i8> %b to <8 x i16>82 %res.1 = add <8 x i16> %za, %zb.183 ret <8 x i16> %res.184 85if.else:86 %zb.2 = sext <8 x i8> %b to <8 x i16>87 %res.2 = sub <8 x i16> %za, %zb.288 ret <8 x i16> %res.289}90 91define <8 x i16> @do_not_sink_nonfree_zext(<8 x i8> %a, <8 x i16> %b, i1 %c) {92;93; NEON-LABEL: @do_not_sink_nonfree_zext(94; NEON-NEXT: entry:95; NEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>96; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]97; NEON: if.then:98; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]99; NEON-NEXT: ret <8 x i16> [[RES_1]]100; NEON: if.else:101; NEON-NEXT: ret <8 x i16> [[B]]102;103; NONEON-LABEL: @do_not_sink_nonfree_zext(104; NONEON-NEXT: entry:105; NONEON-NEXT: [[ZA:%.*]] = zext <8 x i8> [[A:%.*]] to <8 x i16>106; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]107; NONEON: if.then:108; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]109; NONEON-NEXT: ret <8 x i16> [[RES_1]]110; NONEON: if.else:111; NONEON-NEXT: ret <8 x i16> [[B]]112;113entry:114 %za = zext <8 x i8> %a to <8 x i16>115 br i1 %c, label %if.then, label %if.else116 117if.then:118 %res.1 = add <8 x i16> %za, %b119 ret <8 x i16> %res.1120 121if.else:122 ret <8 x i16> %b123}124 125define <8 x i16> @do_not_sink_nonfree_sext(<8 x i8> %a, <8 x i16> %b, i1 %c) {126; CHECK-LABEL: @do_not_sink_nonfree_sext(127; CHECK-NEXT: entry:128; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]129; CHECK: if.then:130; CHECK-NEXT: [[ZB_1:%.*]] = sext <8 x i8> [[B:%.*]] to <8 x i16>131; CHECK-NEXT: [[TMP0:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>132; CHECK-NEXT: [[RES_1:%.*]] = add <8 x i16> [[TMP0]], [[ZB_1]]133; CHECK-NEXT: ret <8 x i16> [[RES_1]]134; CHECK: if.else:135; CHECK-NEXT: [[ZB_2:%.*]] = sext <8 x i8> [[B]] to <8 x i16>136; CHECK-NEXT: ret <8 x i16> [[ZB_2]]137;138; NEON-LABEL: @do_not_sink_nonfree_sext(139; NEON-NEXT: entry:140; NEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>141; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]142; NEON: if.then:143; NEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]144; NEON-NEXT: ret <8 x i16> [[RES_1]]145; NEON: if.else:146; NEON-NEXT: ret <8 x i16> [[B]]147;148; NONEON-LABEL: @do_not_sink_nonfree_sext(149; NONEON-NEXT: entry:150; NONEON-NEXT: [[ZA:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i16>151; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]152; NONEON: if.then:153; NONEON-NEXT: [[RES_1:%.*]] = add <8 x i16> [[ZA]], [[B:%.*]]154; NONEON-NEXT: ret <8 x i16> [[RES_1]]155; NONEON: if.else:156; NONEON-NEXT: ret <8 x i16> [[B]]157;158entry:159 %za = sext <8 x i8> %a to <8 x i16>160 br i1 %c, label %if.then, label %if.else161 162if.then:163 %res.1 = add <8 x i16> %za, %b164 ret <8 x i16> %res.1165 166if.else:167 ret <8 x i16> %b168}169 170declare void @user1(<8 x i16>)171 172; Exts can be sunk.173define <8 x i16> @sink_shufflevector_ext_subadd_multiuse(<16 x i8> %a, <16 x i8> %b, i1 %c) {174; NEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(175; NEON-NEXT: entry:176; NEON-NEXT: [[S1:%.*]] = shufflevector <16 x i8> [[A:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>177; NEON-NEXT: [[S3:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>178; NEON-NEXT: [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>179; NEON-NEXT: call void @user1(<8 x i16> [[Z3]])180; NEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]181; NEON: if.then:182; NEON-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[B:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>183; NEON-NEXT: [[TMP0:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>184; NEON-NEXT: [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>185; NEON-NEXT: [[RES1:%.*]] = add <8 x i16> [[TMP0]], [[Z2]]186; NEON-NEXT: ret <8 x i16> [[RES1]]187; NEON: if.else:188; NEON-NEXT: [[S4:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>189; NEON-NEXT: [[TMP1:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>190; NEON-NEXT: [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>191; NEON-NEXT: [[RES2:%.*]] = sub <8 x i16> [[TMP1]], [[Z4]]192; NEON-NEXT: ret <8 x i16> [[RES2]]193;194; NONEON-LABEL: @sink_shufflevector_ext_subadd_multiuse(195; NONEON-NEXT: entry:196; NONEON-NEXT: [[S1:%.*]] = shufflevector <16 x i8> [[A:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>197; NONEON-NEXT: [[Z1:%.*]] = zext <8 x i8> [[S1]] to <8 x i16>198; NONEON-NEXT: [[S3:%.*]] = shufflevector <16 x i8> [[A]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>199; NONEON-NEXT: [[Z3:%.*]] = sext <8 x i8> [[S3]] to <8 x i16>200; NONEON-NEXT: call void @user1(<8 x i16> [[Z3]])201; NONEON-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]202; NONEON: if.then:203; NONEON-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[B:%.*]], <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>204; NONEON-NEXT: [[Z2:%.*]] = zext <8 x i8> [[S2]] to <8 x i16>205; NONEON-NEXT: [[RES1:%.*]] = add <8 x i16> [[Z1]], [[Z2]]206; NONEON-NEXT: ret <8 x i16> [[RES1]]207; NONEON: if.else:208; NONEON-NEXT: [[S4:%.*]] = shufflevector <16 x i8> [[B]], <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>209; NONEON-NEXT: [[Z4:%.*]] = sext <8 x i8> [[S4]] to <8 x i16>210; NONEON-NEXT: [[RES2:%.*]] = sub <8 x i16> [[Z3]], [[Z4]]211; NONEON-NEXT: ret <8 x i16> [[RES2]]212;213entry:214 %s1 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>215 %z1 = zext <8 x i8> %s1 to <8 x i16>216 %s3 = shufflevector <16 x i8> %a, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>217 %z3 = sext <8 x i8> %s3 to <8 x i16>218 call void @user1(<8 x i16> %z3)219 br i1 %c, label %if.then, label %if.else220 221if.then:222 %s2 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>223 %z2 = zext <8 x i8> %s2 to <8 x i16>224 %res1 = add <8 x i16> %z1, %z2225 ret <8 x i16> %res1226 227if.else:228 %s4 = shufflevector <16 x i8> %b, <16 x i8> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>229 %z4 = sext <8 x i8> %s4 to <8 x i16>230 %res2 = sub <8 x i16> %z3, %z4231 ret <8 x i16> %res2232}233