[llvm] 2121e35 - Revert "[InstCombine] Expand `foldSelectICmpAndOr` -> `foldSelectICmpAndBinOp` to work for more binops"
David Spickett via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 17 03:14:20 PDT 2023
Author: David Spickett
Date: 2023-08-17T10:13:47Z
New Revision: 2121e35ac2375b20a7c675c4e2108c1c94c1322f
URL: https://github.com/llvm/llvm-project/commit/2121e35ac2375b20a7c675c4e2108c1c94c1322f
DIFF: https://github.com/llvm/llvm-project/commit/2121e35ac2375b20a7c675c4e2108c1c94c1322f.diff
LOG: Revert "[InstCombine] Expand `foldSelectICmpAndOr` -> `foldSelectICmpAndBinOp` to work for more binops"
This reverts commit d3402bc4460acefbc3d5278743601fa090784614.
This has caused a second stage build failure on one of our Armv7 32 bit builders:
https://lab.llvm.org/buildbot/#/builders/182/builds/7193
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 0e663338d139b6..d5be03dd425773 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -689,32 +689,25 @@ static Value *foldSelectICmpLshrAshr(const ICmpInst *IC, Value *TrueVal,
}
/// We want to turn:
-/// (select (icmp eq (and X, C1), 0), Y, (BinOp Y, C2))
+/// (select (icmp eq (and X, C1), 0), Y, (or Y, C2))
/// into:
-/// IF C2 u>= C1
-/// (BinOp (shl (and X, C1), C3), Y)
-/// ELSE
-/// (BinOp (lshr (and X, C1), C3), Y)
+/// (or (shl (and X, C1), C3), Y)
/// iff:
-/// 0 on the RHS is the identity value (i.e add, xor, shl, etc...)
/// C1 and C2 are both powers of 2
/// where:
-/// IF C2 u>= C1
-/// C3 = Log(C2) - Log(C1)
-/// ELSE
-/// C3 = Log(C1) - Log(C2)
+/// C3 = Log(C2) - Log(C1)
///
/// This transform handles cases where:
/// 1. The icmp predicate is inverted
/// 2. The select operands are reversed
/// 3. The magnitude of C2 and C1 are flipped
-static Value *foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal,
+static Value *foldSelectICmpAndOr(const ICmpInst *IC, Value *TrueVal,
Value *FalseVal,
InstCombiner::BuilderTy &Builder) {
// Only handle integer compares. Also, if this is a vector select, we need a
// vector compare.
if (!TrueVal->getType()->isIntOrIntVectorTy() ||
- TrueVal->getType()->isVectorTy() != IC->getType()->isVectorTy())
+ TrueVal->getType()->isVectorTy() != IC->getType()->isVectorTy())
return nullptr;
Value *CmpLHS = IC->getOperand(0);
@@ -742,28 +735,21 @@ static Value *foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal,
NeedAnd = true;
}
- Value *Y, *V = CmpLHS;
- BinaryOperator *BinOp;
+ Value *Or, *Y, *V = CmpLHS;
const APInt *C2;
bool NeedXor;
- if (match(FalseVal, m_BinOp(m_Specific(TrueVal), m_Power2(C2)))) {
+ if (match(FalseVal, m_Or(m_Specific(TrueVal), m_Power2(C2)))) {
Y = TrueVal;
- BinOp = cast<BinaryOperator>(FalseVal);
+ Or = FalseVal;
NeedXor = Pred == ICmpInst::ICMP_NE;
- } else if (match(TrueVal, m_BinOp(m_Specific(FalseVal), m_Power2(C2)))) {
+ } else if (match(TrueVal, m_Or(m_Specific(FalseVal), m_Power2(C2)))) {
Y = FalseVal;
- BinOp = cast<BinaryOperator>(TrueVal);
+ Or = TrueVal;
NeedXor = Pred == ICmpInst::ICMP_EQ;
} else {
return nullptr;
}
- // Check that 0 on RHS is identity value for this binop.
- if (!ConstantExpr::getBinOpIdentity(BinOp->getOpcode(), BinOp->getType(),
- /*AllowRHSConstant*/ true)
- ->isNullValue())
- return nullptr;
-
unsigned C2Log = C2->logBase2();
bool NeedShift = C1Log != C2Log;
@@ -772,7 +758,7 @@ static Value *foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal,
// Make sure we don't create more instructions than we save.
if ((NeedShift + NeedXor + NeedZExtTrunc + NeedAnd) >
- (IC->hasOneUse() + BinOp->hasOneUse()))
+ (IC->hasOneUse() + Or->hasOneUse()))
return nullptr;
if (NeedAnd) {
@@ -793,7 +779,7 @@ static Value *foldSelectICmpAndBinOp(const ICmpInst *IC, Value *TrueVal,
if (NeedXor)
V = Builder.CreateXor(V, *C2);
- return Builder.CreateBinOp(BinOp->getOpcode(), V, Y);
+ return Builder.CreateOr(V, Y);
}
/// Canonicalize a set or clear of a masked set of constant bits to
@@ -1802,7 +1788,7 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
if (Instruction *V = foldSelectZeroOrOnes(ICI, TrueVal, FalseVal, Builder))
return V;
- if (Value *V = foldSelectICmpAndBinOp(ICI, TrueVal, FalseVal, Builder))
+ if (Value *V = foldSelectICmpAndOr(ICI, TrueVal, FalseVal, Builder))
return replaceInstUsesWith(SI, V);
if (Value *V = foldSelectICmpLshrAshr(ICI, TrueVal, FalseVal, Builder))
diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
index 1b4b83db5f2fae..b83ac3b92637a4 100644
--- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
+++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
@@ -36,9 +36,10 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec(<2 x i32> %x, <2 x i32> %y) {
define i32 @select_icmp_eq_and_1_0_xor_2(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_xor_2(
-; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 1
@@ -93,9 +94,10 @@ define <2 x i32> @select_icmp_eq_and_32_0_or_8_vec(<2 x i32> %x, <2 x i32> %y) {
define i32 @select_icmp_eq_and_32_0_xor_8(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_32_0_xor_8(
-; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[X:%.*]], 2
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 8
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 32
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 8
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 32
@@ -151,8 +153,9 @@ define <2 x i32> @select_icmp_ne_0_and_4096_or_4096_vec(<2 x i32> %x, <2 x i32>
define i32 @select_icmp_ne_0_and_4096_xor_4096(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_ne_0_and_4096_xor_4096(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[AND]], [[Y:%.*]]
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], 4096
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 4096
@@ -206,7 +209,9 @@ define <2 x i32> @select_icmp_eq_and_4096_0_or_4096_vec(<2 x i32> %x, <2 x i32>
define i32 @select_icmp_eq_and_4096_0_xor_4096(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_4096_0_xor_4096(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[AND]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 4096
@@ -262,8 +267,8 @@ define <2 x i32> @select_icmp_eq_0_and_1_or_1_vec(<2 x i64> %x, <2 x i32> %y) {
define i32 @select_icmp_eq_0_and_1_xor_1(i64 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_0_and_1_xor_1(
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 1
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP2]], [[Y:%.*]]
+; CHECK-NEXT: [[XOR:%.*]] = and i32 [[TMP1]], 1
+; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[XOR]], [[Y:%.*]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i64 %x, 1
@@ -305,10 +310,10 @@ define i32 @select_icmp_ne_0_and_4096_or_32(i32 %x, i32 %y) {
define i32 @select_icmp_ne_0_and_4096_xor_32(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_ne_0_and_4096_xor_32(
-; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[X:%.*]], 7
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 32
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP2]], 32
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 32
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 4096
@@ -365,10 +370,10 @@ define <2 x i32> @select_icmp_ne_0_and_32_or_4096_vec(<2 x i32> %x, <2 x i32> %y
define i32 @select_icmp_ne_0_and_32_xor_4096(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_ne_0_and_32_xor_4096(
-; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 7
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 4096
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP2]], 4096
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 32
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 32
@@ -527,8 +532,9 @@ define i32 @select_icmp_and_8_eq_0_xor_8(i32 %x) {
define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_xor_8(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8
-; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[AND]] to i64
-; CHECK-NEXT: [[Y_XOR:%.*]] = xor i64 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[Y:%.*]], 8
+; CHECK-NEXT: [[Y_XOR:%.*]] = select i1 [[CMP]], i64 [[Y]], i64 [[XOR]]
; CHECK-NEXT: ret i64 [[Y_XOR]]
;
%and = and i32 %x, 8
@@ -541,9 +547,9 @@ define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) {
define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) {
; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_xor_8(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 8
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[AND]], 8
-; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
-; CHECK-NEXT: [[XOR_Y:%.*]] = xor i64 [[TMP2]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[Y:%.*]], 8
+; CHECK-NEXT: [[XOR_Y:%.*]] = select i1 [[CMP]], i64 [[XOR]], i64 [[Y]]
; CHECK-NEXT: ret i64 [[XOR_Y]]
;
%and = and i32 %x, 8
@@ -664,9 +670,10 @@ define <2 x i32> @test68vec(<2 x i32> %x, <2 x i32> %y) {
define i32 @test68_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @test68_xor(
-; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[X:%.*]], 6
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 128
@@ -723,10 +730,10 @@ define <2 x i32> @test69vec(<2 x i32> %x, <2 x i32> %y) {
define i32 @test69_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @test69_xor(
-; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[X:%.*]], 6
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2
-; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP2]], 2
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 128
@@ -798,10 +805,10 @@ define i32 @shift_no_xor_multiuse_or(i32 %x, i32 %y) {
define i32 @shift_no_xor_multiuse_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @shift_no_xor_multiuse_xor(
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], [[Y]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]]
; CHECK-NEXT: ret i32 [[RES]]
;
@@ -849,8 +856,9 @@ define i32 @no_shift_no_xor_multiuse_or(i32 %x, i32 %y) {
define i32 @no_shift_no_xor_multiuse_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @no_shift_no_xor_multiuse_xor(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[AND]], [[Y]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]]
; CHECK-NEXT: ret i32 [[RES]]
;
@@ -899,9 +907,9 @@ define i32 @no_shift_xor_multiuse_or(i32 %x, i32 %y) {
define i32 @no_shift_xor_multiuse_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @no_shift_xor_multiuse_xor(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[AND]], [[Y]]
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], 4096
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]]
; CHECK-NEXT: ret i32 [[RES]]
;
@@ -1004,8 +1012,8 @@ define i32 @shift_no_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp_with_xor(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[AND]], 1
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: ret i32 [[RES]]
@@ -1060,7 +1068,8 @@ define i32 @no_shift_no_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w
; CHECK-LABEL: @no_shift_no_xor_multiuse_cmp_with_xor(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[AND]], [[Y:%.*]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: ret i32 [[RES]]
@@ -1116,8 +1125,8 @@ define i32 @no_shift_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @no_shift_xor_multiuse_cmp_with_xor(
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[AND]], [[Y:%.*]]
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[TMP1]], 4096
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: ret i32 [[RES]]
@@ -1296,7 +1305,7 @@ define i32 @no_shift_no_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[AND]], [[Y]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[XOR]]
@@ -1597,9 +1606,10 @@ define i64 @xor_i8_to_i64_shl_save_and_eq(i8 %x, i64 %y) {
define i64 @xor_i8_to_i64_shl_save_and_ne(i8 %x, i64 %y) {
; CHECK-LABEL: @xor_i8_to_i64_shl_save_and_ne(
-; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i64
-; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 63
-; CHECK-NEXT: [[R:%.*]] = xor i64 [[TMP2]], [[Y:%.*]]
+; CHECK-NEXT: [[XX:%.*]] = and i8 [[X:%.*]], 1
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[XX]], 0
+; CHECK-NEXT: [[Z:%.*]] = xor i64 [[Y:%.*]], -9223372036854775808
+; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP_NOT]], i64 [[Y]], i64 [[Z]]
; CHECK-NEXT: ret i64 [[R]]
;
%xx = and i8 %x, 1
More information about the llvm-commits
mailing list