brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.5 KiB · 834d48f Raw
686 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4 5define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) {6; CHECK-LABEL: @foo(7; CHECK-NEXT:    [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]8; CHECK-NEXT:    [[J:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]9; CHECK-NEXT:    ret i32 [[J]]10;11  %e = icmp slt i32 %a, %b12  %f = sext i1 %e to i3213  %g = and i32 %c, %f14  %h = xor i32 %f, -115  %i = and i32 %d, %h16  %j = or i32 %g, %i17  ret i32 %j18}19 20define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) {21; CHECK-LABEL: @bar(22; CHECK-NEXT:    [[E_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]23; CHECK-NEXT:    [[J:%.*]] = select i1 [[E_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]24; CHECK-NEXT:    ret i32 [[J]]25;26  %e = icmp slt i32 %a, %b27  %f = sext i1 %e to i3228  %g = and i32 %c, %f29  %h = xor i32 %f, -130  %i = and i32 %d, %h31  %j = or i32 %i, %g32  ret i32 %j33}34 35define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) {36; CHECK-LABEL: @goo(37; CHECK-NEXT:    [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]38; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]39; CHECK-NEXT:    ret i32 [[T3]]40;41  %t0 = icmp slt i32 %a, %b42  %iftmp.0.0 = select i1 %t0, i32 -1, i32 043  %t1 = and i32 %iftmp.0.0, %c44  %not = xor i32 %iftmp.0.0, -145  %t2 = and i32 %not, %d46  %t3 = or i32 %t1, %t247  ret i32 %t348}49 50define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) {51; CHECK-LABEL: @poo(52; CHECK-NEXT:    [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]53; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]54; CHECK-NEXT:    ret i32 [[T3]]55;56  %t0 = icmp slt i32 %a, %b57  %iftmp.0.0 = select i1 %t0, i32 -1, i32 058  %t1 = and i32 %iftmp.0.0, %c59  %iftmp = select i1 %t0, i32 0, i32 -160  %t2 = and i32 %iftmp, %d61  %t3 = or i32 %t1, %t262  ret i32 %t363}64 65; PR32791 - https://bugs.llvm.org//show_bug.cgi?id=3279166; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.67 68define i32 @fold_inverted_icmp_preds(i32 %a, i32 %b, i32 %c, i32 %d) {69; CHECK-LABEL: @fold_inverted_icmp_preds(70; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]71; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 072; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]73; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 0, i32 [[D:%.*]]74; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]75; CHECK-NEXT:    ret i32 [[OR]]76;77  %cmp1 = icmp slt i32 %a, %b78  %sel1 = select i1 %cmp1, i32 %c, i32 079  %cmp2 = icmp sge i32 %a, %b80  %sel2 = select i1 %cmp2, i32 %d, i32 081  %or = or i32 %sel1, %sel282  ret i32 %or83}84 85; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.86 87define i32 @fold_inverted_icmp_preds_reverse(i32 %a, i32 %b, i32 %c, i32 %d) {88; CHECK-LABEL: @fold_inverted_icmp_preds_reverse(89; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]90; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 [[C:%.*]]91; CHECK-NEXT:    [[CMP2_NOT:%.*]] = icmp slt i32 [[A]], [[B]]92; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2_NOT]], i32 [[D:%.*]], i32 093; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]94; CHECK-NEXT:    ret i32 [[OR]]95;96  %cmp1 = icmp slt i32 %a, %b97  %sel1 = select i1 %cmp1, i32 0, i32 %c98  %cmp2 = icmp sge i32 %a, %b99  %sel2 = select i1 %cmp2, i32 0, i32 %d100  %or = or i32 %sel1, %sel2101  ret i32 %or102}103 104; TODO: Should fcmp have the same sort of predicate canonicalization as icmp?105 106define i32 @fold_inverted_fcmp_preds(float %a, float %b, i32 %c, i32 %d) {107; CHECK-LABEL: @fold_inverted_fcmp_preds(108; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt float [[A:%.*]], [[B:%.*]]109; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[CMP1]], i32 [[C:%.*]], i32 0110; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uge float [[A]], [[B]]111; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[CMP2]], i32 [[D:%.*]], i32 0112; CHECK-NEXT:    [[OR:%.*]] = or i32 [[SEL1]], [[SEL2]]113; CHECK-NEXT:    ret i32 [[OR]]114;115  %cmp1 = fcmp olt float %a, %b116  %sel1 = select i1 %cmp1, i32 %c, i32 0117  %cmp2 = fcmp uge float %a, %b118  %sel2 = select i1 %cmp2, i32 %d, i32 0119  %or = or i32 %sel1, %sel2120  ret i32 %or121}122 123; The 2nd compare/select are canonicalized, so CSE and another round of instcombine or some other pass will fold this.124 125define <2 x i32> @fold_inverted_icmp_vector_preds(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c, <2 x i32> %d) {126; CHECK-LABEL: @fold_inverted_icmp_vector_preds(127; CHECK-NEXT:    [[CMP1_NOT:%.*]] = icmp eq <2 x i32> [[A:%.*]], [[B:%.*]]128; CHECK-NEXT:    [[SEL1:%.*]] = select <2 x i1> [[CMP1_NOT]], <2 x i32> zeroinitializer, <2 x i32> [[C:%.*]]129; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <2 x i32> [[A]], [[B]]130; CHECK-NEXT:    [[SEL2:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[D:%.*]], <2 x i32> zeroinitializer131; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[SEL1]], [[SEL2]]132; CHECK-NEXT:    ret <2 x i32> [[OR]]133;134  %cmp1 = icmp ne <2 x i32> %a, %b135  %sel1 = select <2 x i1> %cmp1, <2 x i32> %c, <2 x i32> <i32 0, i32 0>136  %cmp2 = icmp eq <2 x i32> %a, %b137  %sel2 = select <2 x i1> %cmp2, <2 x i32> %d, <2 x i32> <i32 0, i32 0>138  %or = or <2 x i32> %sel1, %sel2139  ret <2 x i32> %or140}141 142define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) {143; CHECK-LABEL: @par(144; CHECK-NEXT:    [[T0_NOT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]145; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T0_NOT]], i32 [[C:%.*]], i32 [[D:%.*]]146; CHECK-NEXT:    ret i32 [[T3]]147;148  %t0 = icmp slt i32 %a, %b149  %iftmp.1.0 = select i1 %t0, i32 -1, i32 0150  %t1 = and i32 %iftmp.1.0, %c151  %not = xor i32 %iftmp.1.0, -1152  %t2 = and i32 %not, %d153  %t3 = or i32 %t1, %t2154  ret i32 %t3155}156 157; In the following tests (8 commutation variants), verify that a bitcast doesn't get158; in the way of a select transform. These bitcasts are common in SSE/AVX and possibly159; other vector code because of canonicalization to i64 elements for vectors.160 161; The fptosi instructions are included to avoid commutation canonicalization based on162; operator weight. Using another cast operator ensures that both operands of all logic163; ops are equally weighted, and this ensures that we're testing all commutation164; possibilities.165 166define <2 x i64> @bitcast_select_swap0(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {167; CHECK-LABEL: @bitcast_select_swap0(168; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>169; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>170; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>171; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>172; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]173; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>174; CHECK-NEXT:    ret <2 x i64> [[OR]]175;176  %sia = fptosi <2 x double> %a to <2 x i64>177  %sib = fptosi <2 x double> %b to <2 x i64>178  %sext = sext <4 x i1> %cmp to <4 x i32>179  %bc1 = bitcast <4 x i32> %sext to <2 x i64>180  %and1 = and <2 x i64> %bc1, %sia181  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>182  %bc2 = bitcast <4 x i32> %neg to <2 x i64>183  %and2 = and <2 x i64> %bc2, %sib184  %or = or <2 x i64> %and1, %and2185  ret <2 x i64> %or186}187 188define <2 x i64> @bitcast_select_swap1(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {189; CHECK-LABEL: @bitcast_select_swap1(190; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>191; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>192; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>193; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>194; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]195; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>196; CHECK-NEXT:    ret <2 x i64> [[OR]]197;198  %sia = fptosi <2 x double> %a to <2 x i64>199  %sib = fptosi <2 x double> %b to <2 x i64>200  %sext = sext <4 x i1> %cmp to <4 x i32>201  %bc1 = bitcast <4 x i32> %sext to <2 x i64>202  %and1 = and <2 x i64> %bc1, %sia203  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>204  %bc2 = bitcast <4 x i32> %neg to <2 x i64>205  %and2 = and <2 x i64> %bc2, %sib206  %or = or <2 x i64> %and2, %and1207  ret <2 x i64> %or208}209 210define <2 x i64> @bitcast_select_swap2(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {211; CHECK-LABEL: @bitcast_select_swap2(212; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>213; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>214; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>215; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>216; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]217; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>218; CHECK-NEXT:    ret <2 x i64> [[OR]]219;220  %sia = fptosi <2 x double> %a to <2 x i64>221  %sib = fptosi <2 x double> %b to <2 x i64>222  %sext = sext <4 x i1> %cmp to <4 x i32>223  %bc1 = bitcast <4 x i32> %sext to <2 x i64>224  %and1 = and <2 x i64> %bc1, %sia225  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>226  %bc2 = bitcast <4 x i32> %neg to <2 x i64>227  %and2 = and <2 x i64> %sib, %bc2228  %or = or <2 x i64> %and1, %and2229  ret <2 x i64> %or230}231 232define <2 x i64> @bitcast_select_swap3(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {233; CHECK-LABEL: @bitcast_select_swap3(234; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>235; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>236; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>237; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>238; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]239; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>240; CHECK-NEXT:    ret <2 x i64> [[OR]]241;242  %sia = fptosi <2 x double> %a to <2 x i64>243  %sib = fptosi <2 x double> %b to <2 x i64>244  %sext = sext <4 x i1> %cmp to <4 x i32>245  %bc1 = bitcast <4 x i32> %sext to <2 x i64>246  %and1 = and <2 x i64> %bc1, %sia247  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>248  %bc2 = bitcast <4 x i32> %neg to <2 x i64>249  %and2 = and <2 x i64> %sib, %bc2250  %or = or <2 x i64> %and2, %and1251  ret <2 x i64> %or252}253 254define <2 x i64> @bitcast_select_swap4(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {255; CHECK-LABEL: @bitcast_select_swap4(256; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>257; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>258; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>259; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>260; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]261; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>262; CHECK-NEXT:    ret <2 x i64> [[OR]]263;264  %sia = fptosi <2 x double> %a to <2 x i64>265  %sib = fptosi <2 x double> %b to <2 x i64>266  %sext = sext <4 x i1> %cmp to <4 x i32>267  %bc1 = bitcast <4 x i32> %sext to <2 x i64>268  %and1 = and <2 x i64> %sia, %bc1269  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>270  %bc2 = bitcast <4 x i32> %neg to <2 x i64>271  %and2 = and <2 x i64> %bc2, %sib272  %or = or <2 x i64> %and1, %and2273  ret <2 x i64> %or274}275 276define <2 x i64> @bitcast_select_swap5(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {277; CHECK-LABEL: @bitcast_select_swap5(278; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>279; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>280; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>281; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>282; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]283; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>284; CHECK-NEXT:    ret <2 x i64> [[OR]]285;286  %sia = fptosi <2 x double> %a to <2 x i64>287  %sib = fptosi <2 x double> %b to <2 x i64>288  %sext = sext <4 x i1> %cmp to <4 x i32>289  %bc1 = bitcast <4 x i32> %sext to <2 x i64>290  %and1 = and <2 x i64> %sia, %bc1291  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>292  %bc2 = bitcast <4 x i32> %neg to <2 x i64>293  %and2 = and <2 x i64> %bc2, %sib294  %or = or <2 x i64> %and2, %and1295  ret <2 x i64> %or296}297 298define <2 x i64> @bitcast_select_swap6(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {299; CHECK-LABEL: @bitcast_select_swap6(300; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>301; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>302; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>303; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>304; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]305; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>306; CHECK-NEXT:    ret <2 x i64> [[OR]]307;308  %sia = fptosi <2 x double> %a to <2 x i64>309  %sib = fptosi <2 x double> %b to <2 x i64>310  %sext = sext <4 x i1> %cmp to <4 x i32>311  %bc1 = bitcast <4 x i32> %sext to <2 x i64>312  %and1 = and <2 x i64> %sia, %bc1313  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>314  %bc2 = bitcast <4 x i32> %neg to <2 x i64>315  %and2 = and <2 x i64> %sib, %bc2316  %or = or <2 x i64> %and1, %and2317  ret <2 x i64> %or318}319 320define <2 x i64> @bitcast_select_swap7(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {321; CHECK-LABEL: @bitcast_select_swap7(322; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>323; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>324; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32>325; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32>326; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i32> [[TMP1]], <4 x i32> [[TMP2]]327; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64>328; CHECK-NEXT:    ret <2 x i64> [[OR]]329;330  %sia = fptosi <2 x double> %a to <2 x i64>331  %sib = fptosi <2 x double> %b to <2 x i64>332  %sext = sext <4 x i1> %cmp to <4 x i32>333  %bc1 = bitcast <4 x i32> %sext to <2 x i64>334  %and1 = and <2 x i64> %sia, %bc1335  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>336  %bc2 = bitcast <4 x i32> %neg to <2 x i64>337  %and2 = and <2 x i64> %sib, %bc2338  %or = or <2 x i64> %and2, %and1339  ret <2 x i64> %or340}341 342define <2 x i64> @bitcast_select_multi_uses(<4 x i1> %cmp, <2 x i64> %a, <2 x i64> %b) {343; CHECK-LABEL: @bitcast_select_multi_uses(344; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[CMP:%.*]] to <4 x i32>345; CHECK-NEXT:    [[BC1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>346; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i64> [[A:%.*]], [[BC1]]347; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>348; CHECK-NEXT:    [[BC2:%.*]] = xor <2 x i64> [[TMP1]], splat (i64 -1)349; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[B:%.*]], [[BC2]]350; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]]351; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i64> [[AND2]], [[BC2]]352; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i64> [[OR]], [[ADD]]353; CHECK-NEXT:    ret <2 x i64> [[SUB]]354;355  %sext = sext <4 x i1> %cmp to <4 x i32>356  %bc1 = bitcast <4 x i32> %sext to <2 x i64>357  %and1 = and <2 x i64> %a, %bc1358  %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1>359  %bc2 = bitcast <4 x i32> %neg to <2 x i64>360  %and2 = and <2 x i64> %b, %bc2361  %or = or <2 x i64> %and2, %and1362  %add = add <2 x i64> %and2, %bc2363  %sub = sub <2 x i64> %or, %add364  ret <2 x i64> %sub365}366 367define i1 @bools(i1 %a, i1 %b, i1 %c) {368; CHECK-LABEL: @bools(369; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]370; CHECK-NEXT:    ret i1 [[OR]]371;372  %not = xor i1 %c, -1373  %and1 = and i1 %not, %a374  %and2 = and i1 %c, %b375  %or = or i1 %and1, %and2376  ret i1 %or377}378 379define i1 @bools_logical(i1 %a, i1 %b, i1 %c) {380; CHECK-LABEL: @bools_logical(381; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]382; CHECK-NEXT:    ret i1 [[OR]]383;384  %not = xor i1 %c, -1385  %and1 = select i1 %not, i1 %a, i1 false386  %and2 = select i1 %c, i1 %b, i1 false387  %or = select i1 %and1, i1 true, i1 %and2388  ret i1 %or389}390 391; Form a select if we know we can get replace 2 simple logic ops.392 393define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {394; CHECK-LABEL: @bools_multi_uses1(395; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true396; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[A:%.*]], [[NOT]]397; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]]398; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[OR]], [[AND1]]399; CHECK-NEXT:    ret i1 [[XOR]]400;401  %not = xor i1 %c, -1402  %and1 = and i1 %not, %a403  %and2 = and i1 %c, %b404  %or = or i1 %and1, %and2405  %xor = xor i1 %or, %and1406  ret i1 %xor407}408 409define i1 @bools_multi_uses1_logical(i1 %a, i1 %b, i1 %c) {410; CHECK-LABEL: @bools_multi_uses1_logical(411; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true412; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false413; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]]414; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[OR]], [[AND1]]415; CHECK-NEXT:    ret i1 [[XOR]]416;417  %not = xor i1 %c, -1418  %and1 = select i1 %not, i1 %a, i1 false419  %and2 = select i1 %c, i1 %b, i1 false420  %or = select i1 %and1, i1 true, i1 %and2421  %xor = xor i1 %or, %and1422  ret i1 %xor423}424 425; Don't replace a cheap logic op with a potentially expensive select426; unless we can also eliminate one of the other original ops.427 428define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) {429; CHECK-LABEL: @bools_multi_uses2(430; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]431; CHECK-NEXT:    ret i1 [[OR]]432;433  %not = xor i1 %c, -1434  %and1 = and i1 %not, %a435  %and2 = and i1 %c, %b436  %or = or i1 %and1, %and2437  %add = add i1 %and1, %and2438  %and3 = and i1 %or, %add439  ret i1 %and3440}441 442define i1 @bools_multi_uses2_logical(i1 %a, i1 %b, i1 %c) {443; CHECK-LABEL: @bools_multi_uses2_logical(444; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true445; CHECK-NEXT:    [[AND1:%.*]] = select i1 [[NOT]], i1 [[A:%.*]], i1 false446; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false447; CHECK-NEXT:    [[OR:%.*]] = select i1 [[C]], i1 [[B]], i1 [[A]]448; CHECK-NEXT:    [[ADD:%.*]] = xor i1 [[AND1]], [[AND2]]449; CHECK-NEXT:    [[AND3:%.*]] = select i1 [[OR]], i1 [[ADD]], i1 false450; CHECK-NEXT:    ret i1 [[AND3]]451;452  %not = xor i1 %c, -1453  %and1 = select i1 %not, i1 %a, i1 false454  %and2 = select i1 %c, i1 %b, i1 false455  %or = select i1 %and1, i1 true, i1 %and2456  %add = add i1 %and1, %and2457  %and3 = select i1 %or, i1 %add, i1 false458  ret i1 %and3459}460 461define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) {462; CHECK-LABEL: @vec_of_bools(463; CHECK-NEXT:    [[OR:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[B:%.*]], <4 x i1> [[A:%.*]]464; CHECK-NEXT:    ret <4 x i1> [[OR]]465;466  %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>467  %and1 = and <4 x i1> %not, %a468  %and2 = and <4 x i1> %b, %c469  %or = or <4 x i1> %and2, %and1470  ret <4 x i1> %or471}472 473define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) {474; CHECK-LABEL: @vec_of_casted_bools(475; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i4 [[B:%.*]] to <4 x i1>476; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i4 [[A:%.*]] to <4 x i1>477; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[TMP1]], <4 x i1> [[TMP2]]478; CHECK-NEXT:    [[OR:%.*]] = bitcast <4 x i1> [[TMP3]] to i4479; CHECK-NEXT:    ret i4 [[OR]]480;481  %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true>482  %bc1 = bitcast <4 x i1> %not to i4483  %bc2 = bitcast <4 x i1> %c to i4484  %and1 = and i4 %a, %bc1485  %and2 = and i4 %bc2, %b486  %or = or i4 %and1, %and2487  ret i4 %or488}489 490; Inverted 'and' constants mean this is a select which is canonicalized to a shuffle.491 492define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) {493; CHECK-LABEL: @vec_sel_consts(494; CHECK-NEXT:    [[OR:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> <i32 0, i32 5, i32 6, i32 3>495; CHECK-NEXT:    ret <4 x i32> [[OR]]496;497  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 -1>498  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 0>499  %or = or <4 x i32> %and1, %and2500  ret <4 x i32> %or501}502 503define <3 x i129> @vec_sel_consts_weird(<3 x i129> %a, <3 x i129> %b) {504; CHECK-LABEL: @vec_sel_consts_weird(505; CHECK-NEXT:    [[OR:%.*]] = shufflevector <3 x i129> [[A:%.*]], <3 x i129> [[B:%.*]], <3 x i32> <i32 0, i32 4, i32 2>506; CHECK-NEXT:    ret <3 x i129> [[OR]]507;508  %and1 = and <3 x i129> %a, <i129 -1, i129 0, i129 -1>509  %and2 = and <3 x i129> %b, <i129 0, i129 -1, i129 0>510  %or = or <3 x i129> %and2, %and1511  ret <3 x i129> %or512}513 514; The mask elements must be inverted for this to be a select.515 516define <4 x i32> @vec_not_sel_consts(<4 x i32> %a, <4 x i32> %b) {517; CHECK-LABEL: @vec_not_sel_consts(518; CHECK-NEXT:    [[AND1:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1, i32 0, i32 0, i32 0>519; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> [[B:%.*]], <i32 0, i32 -1, i32 0, i32 -1>520; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]]521; CHECK-NEXT:    ret <4 x i32> [[OR]]522;523  %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0>524  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1>525  %or = or <4 x i32> %and1, %and2526  ret <4 x i32> %or527}528 529define <4 x i32> @vec_not_sel_consts_undef_elts(<4 x i32> %a, <4 x i32> %b) {530; CHECK-LABEL: @vec_not_sel_consts_undef_elts(531; CHECK-NEXT:    [[AND1:%.*]] = and <4 x i32> [[A:%.*]], <i32 -1, i32 undef, i32 0, i32 0>532; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> [[B:%.*]], <i32 0, i32 -1, i32 0, i32 undef>533; CHECK-NEXT:    [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]]534; CHECK-NEXT:    ret <4 x i32> [[OR]]535;536  %and1 = and <4 x i32> %a, <i32 -1, i32 undef, i32 0, i32 0>537  %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 undef>538  %or = or <4 x i32> %and1, %and2539  ret <4 x i32> %or540}541 542; The inverted constants may be operands of xor instructions.543 544define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {545; CHECK-LABEL: @vec_sel_xor(546; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], <i1 false, i1 true, i1 true, i1 true>547; CHECK-NEXT:    [[OR:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]548; CHECK-NEXT:    ret <4 x i32> [[OR]]549;550  %mask = sext <4 x i1> %c to <4 x i32>551  %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>552  %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>553  %and1 = and <4 x i32> %not_mask_flip1, %a554  %and2 = and <4 x i32> %mask_flip1, %b555  %or = or <4 x i32> %and1, %and2556  ret <4 x i32> %or557}558 559; Allow the transform even if the mask values have multiple uses because560; there's still a net reduction of instructions from removing the and/and/or.561 562define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) {563; CHECK-LABEL: @vec_sel_xor_multi_use(564; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[C:%.*]], <i1 true, i1 false, i1 false, i1 false>565; CHECK-NEXT:    [[MASK_FLIP1:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32>566; CHECK-NEXT:    [[TMP2:%.*]] = xor <4 x i1> [[C]], <i1 false, i1 true, i1 true, i1 true>567; CHECK-NEXT:    [[OR:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]568; CHECK-NEXT:    [[ADD:%.*]] = add <4 x i32> [[OR]], [[MASK_FLIP1]]569; CHECK-NEXT:    ret <4 x i32> [[ADD]]570;571  %mask = sext <4 x i1> %c to <4 x i32>572  %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0>573  %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1>574  %and1 = and <4 x i32> %not_mask_flip1, %a575  %and2 = and <4 x i32> %mask_flip1, %b576  %or = or <4 x i32> %and1, %and2577  %add = add <4 x i32> %or, %mask_flip1578  ret <4 x i32> %add579}580 581; The 'ashr' guarantees that we have a bitmask, so this is select with truncated condition.582 583define i32 @allSignBits(i32 %cond, i32 %tval, i32 %fval) {584; CHECK-LABEL: @allSignBits(585; CHECK-NEXT:    [[ISNEG1:%.*]] = icmp slt i32 [[COND:%.*]], 0586; CHECK-NEXT:    [[A1:%.*]] = select i1 [[ISNEG1]], i32 [[TVAL:%.*]], i32 0587; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[COND]], 0588; CHECK-NEXT:    [[A2:%.*]] = select i1 [[ISNEG]], i32 0, i32 [[FVAL:%.*]]589; CHECK-NEXT:    [[SEL:%.*]] = or i32 [[A1]], [[A2]]590; CHECK-NEXT:    ret i32 [[SEL]]591;592  %bitmask = ashr i32 %cond, 31593  %not_bitmask = xor i32 %bitmask, -1594  %a1 = and i32 %tval, %bitmask595  %a2 = and i32 %not_bitmask, %fval596  %sel = or i32 %a1, %a2597  ret i32 %sel598}599 600define <4 x i8> @allSignBits_vec(<4 x i8> %cond, <4 x i8> %tval, <4 x i8> %fval) {601; CHECK-LABEL: @allSignBits_vec(602; CHECK-NEXT:    [[ISNEG1:%.*]] = icmp slt <4 x i8> [[COND:%.*]], zeroinitializer603; CHECK-NEXT:    [[A1:%.*]] = select <4 x i1> [[ISNEG1]], <4 x i8> [[TVAL:%.*]], <4 x i8> zeroinitializer604; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <4 x i8> [[COND]], zeroinitializer605; CHECK-NEXT:    [[A2:%.*]] = select <4 x i1> [[ISNEG]], <4 x i8> zeroinitializer, <4 x i8> [[FVAL:%.*]]606; CHECK-NEXT:    [[SEL:%.*]] = or <4 x i8> [[A2]], [[A1]]607; CHECK-NEXT:    ret <4 x i8> [[SEL]]608;609  %bitmask = ashr <4 x i8> %cond, <i8 7, i8 7, i8 7, i8 7>610  %not_bitmask = xor <4 x i8> %bitmask, <i8 -1, i8 -1, i8 -1, i8 -1>611  %a1 = and <4 x i8> %tval, %bitmask612  %a2 = and <4 x i8> %fval, %not_bitmask613  %sel = or <4 x i8> %a2, %a1614  ret <4 x i8> %sel615}616 617; Negative test - make sure that bitcasts from FP do not cause a crash.618 619define <2 x i64> @fp_bitcast(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) {620; CHECK-LABEL: @fp_bitcast(621; CHECK-NEXT:    [[SIA:%.*]] = fptosi <2 x double> [[A:%.*]] to <2 x i64>622; CHECK-NEXT:    [[SIB:%.*]] = fptosi <2 x double> [[B:%.*]] to <2 x i64>623; CHECK-NEXT:    [[BC1:%.*]] = bitcast <2 x double> [[A]] to <2 x i64>624; CHECK-NEXT:    [[AND1:%.*]] = and <2 x i64> [[SIA]], [[BC1]]625; CHECK-NEXT:    [[BC2:%.*]] = bitcast <2 x double> [[B]] to <2 x i64>626; CHECK-NEXT:    [[AND2:%.*]] = and <2 x i64> [[SIB]], [[BC2]]627; CHECK-NEXT:    [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]]628; CHECK-NEXT:    ret <2 x i64> [[OR]]629;630  %sia = fptosi <2 x double> %a to <2 x i64>631  %sib = fptosi <2 x double> %b to <2 x i64>632  %bc1 = bitcast <2 x double> %a to <2 x i64>633  %and1 = and <2 x i64> %sia, %bc1634  %bc2 = bitcast <2 x double> %b to <2 x i64>635  %and2 = and <2 x i64> %sib, %bc2636  %or = or <2 x i64> %and2, %and1637  ret <2 x i64> %or638}639 640define <4 x i32> @computesignbits_through_shuffles(<4 x float> %x, <4 x float> %y, <4 x float> %z) {641; CHECK-LABEL: @computesignbits_through_shuffles(642; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole <4 x float> [[X:%.*]], [[Y:%.*]]643; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <4 x i1> [[CMP]], <4 x i1> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>644; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i1> [[CMP]], <4 x i1> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3>645; CHECK-NEXT:    [[TMP3:%.*]] = or <4 x i1> [[TMP4]], [[TMP2]]646; CHECK-NEXT:    [[S3:%.*]] = shufflevector <4 x i1> [[TMP3]], <4 x i1> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>647; CHECK-NEXT:    [[S4:%.*]] = shufflevector <4 x i1> [[TMP3]], <4 x i1> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3>648; CHECK-NEXT:    [[TMP1:%.*]] = or <4 x i1> [[S3]], [[S4]]649; CHECK-NEXT:    [[SEL_V:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[Z:%.*]], <4 x float> [[X]]650; CHECK-NEXT:    [[SEL:%.*]] = bitcast <4 x float> [[SEL_V]] to <4 x i32>651; CHECK-NEXT:    ret <4 x i32> [[SEL]]652;653  %cmp = fcmp ole <4 x float> %x, %y654  %sext = sext <4 x i1> %cmp to <4 x i32>655  %s1 = shufflevector <4 x i32> %sext, <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>656  %s2 = shufflevector <4 x i32> %sext, <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3>657  %shuf_or1 = or <4 x i32> %s1, %s2658  %s3 = shufflevector <4 x i32> %shuf_or1, <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>659  %s4 = shufflevector <4 x i32> %shuf_or1, <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 3, i32 3>660  %shuf_or2 = or <4 x i32> %s3, %s4661  %not_or2 = xor <4 x i32> %shuf_or2, <i32 -1, i32 -1, i32 -1, i32 -1>662  %xbc = bitcast <4 x float> %x to <4 x i32>663  %zbc = bitcast <4 x float> %z to <4 x i32>664  %and1 = and <4 x i32> %not_or2, %xbc665  %and2 = and <4 x i32> %shuf_or2, %zbc666  %sel = or <4 x i32> %and1, %and2667  ret <4 x i32> %sel668}669 670define <4 x i32> @computesignbits_through_two_input_shuffle(<4 x i32> %x, <4 x i32> %y, <4 x i1> %cond1, <4 x i1> %cond2) {671; CHECK-LABEL: @computesignbits_through_two_input_shuffle(672; CHECK-NEXT:    [[COND:%.*]] = shufflevector <4 x i1> [[COND1:%.*]], <4 x i1> [[COND2:%.*]], <4 x i32> <i32 0, i32 2, i32 4, i32 6>673; CHECK-NEXT:    [[SEL:%.*]] = select <4 x i1> [[COND]], <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]]674; CHECK-NEXT:    ret <4 x i32> [[SEL]]675;676  %sext1 = sext <4 x i1> %cond1 to <4 x i32>677  %sext2 = sext <4 x i1> %cond2 to <4 x i32>678  %cond = shufflevector <4 x i32> %sext1, <4 x i32> %sext2, <4 x i32> <i32 0, i32 2, i32 4, i32 6>679  %notcond = xor <4 x i32> %cond, <i32 -1, i32 -1, i32 -1, i32 -1>680  %and1 = and <4 x i32> %notcond, %x681  %and2 = and <4 x i32> %cond, %y682  %sel = or <4 x i32> %and1, %and2683  ret <4 x i32> %sel684}685 686