diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index b46d4baf72a26..c94e642a47b50 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -6823,6 +6823,23 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, }; return true; } + + // select Cond, 0, Pow2 --> (zext (!Cond)) << log2(Pow2) + if (FalseValue.isPowerOf2() && TrueValue.isZero()) { + MatchInfo = [=](MachineIRBuilder &B) { + B.setInstrAndDebugLoc(*Select); + Register Not = MRI.createGenericVirtualRegister(CondTy); + B.buildNot(Not, Cond); + Register Inner = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Inner, Not); + // The shift amount must be scalar. + LLT ShiftTy = TrueTy.isVector() ? TrueTy.getElementType() : TrueTy; + auto ShAmtC = B.buildConstant(ShiftTy, FalseValue.exactLogBase2()); + B.buildShl(Dest, Inner, ShAmtC, Flags); + }; + return true; + } + // select Cond, -1, C --> or (sext Cond), C if (TrueValue.isAllOnes()) { MatchInfo = [=](MachineIRBuilder &B) { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir index 86fa12aa064ac..4afa0d4378fe1 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir @@ -436,6 +436,36 @@ body: | $w0 = COPY %ext(s32) ... --- +# select cond, 0, 64 --> (zext (!Cond)) << log2(Pow2) +name: select_cond_0_64_to_shift +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_cond_0_64_to_shift + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true + ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR %c, [[C]] + ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[XOR]](s1) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 6 + ; CHECK-NEXT: %sel:_(s8) = G_SHL [[ZEXT]], [[C1]](s8) + ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8) + ; CHECK-NEXT: $w0 = COPY %ext(s32) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %2:_(s64) = COPY $x2 + %c:_(s1) = G_TRUNC %0 + %t:_(s1) = G_TRUNC %1 + %f:_(s1) = G_TRUNC %2 + %two:_(s8) = G_CONSTANT i8 0 + %one:_(s8) = G_CONSTANT i8 64 + %sel:_(s8) = G_SELECT %c, %two, %one + %ext:_(s32) = G_ANYEXT %sel + $w0 = COPY %ext(s32) +... +--- # select cond, -1, 0 --> sext Cond name: select_cond_minus_1_0_to_sext_cond body: |