From af14bbf8c25cffb4b871f1986a189ca7628d32d2 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 9 Oct 2020 14:22:19 +0100 Subject: [PATCH] [InstCombine] foldShiftOfShiftedLogic - add support for nonuniform constant vectors --- .../InstCombine/InstCombineShifts.cpp | 12 ++++++---- test/Transforms/InstCombine/shift-logic.ll | 24 +++++++++---------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index 6ead851033d..828002f44d4 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -328,8 +328,8 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I, if (!LogicInst || !LogicInst->isBitwiseLogicOp() || !LogicInst->hasOneUse()) return nullptr; - const APInt *C0, *C1; - if (!match(I.getOperand(1), m_APInt(C1))) + Constant *C0, *C1; + if (!match(I.getOperand(1), m_Constant(C1))) return nullptr; Instruction::BinaryOps ShiftOpcode = I.getOpcode(); @@ -341,9 +341,11 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I, Value *X, *Y; auto matchFirstShift = [&](Value *V) { BinaryOperator *BO; + APInt Threshold(Ty->getScalarSizeInBits(), Ty->getScalarSizeInBits()); return match(V, m_BinOp(BO)) && BO->getOpcode() == ShiftOpcode && - match(V, m_OneUse(m_Shift(m_Value(X), m_APInt(C0)))) && - (*C0 + *C1).ult(Ty->getScalarSizeInBits()); + match(V, m_OneUse(m_Shift(m_Value(X), m_Constant(C0)))) && + match(ConstantExpr::getAdd(C0, C1), + m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold)); }; // Logic ops are commutative, so check each operand for a match. @@ -355,7 +357,7 @@ static Instruction *foldShiftOfShiftedLogic(BinaryOperator &I, return nullptr; // shift (logic (shift X, C0), Y), C1 -> logic (shift X, C0+C1), (shift Y, C1) - Constant *ShiftSumC = ConstantInt::get(Ty, *C0 + *C1); + Constant *ShiftSumC = ConstantExpr::getAdd(C0, C1); Value *NewShift1 = Builder.CreateBinOp(ShiftOpcode, X, ShiftSumC); Value *NewShift2 = Builder.CreateBinOp(ShiftOpcode, Y, I.getOperand(1)); return BinaryOperator::Create(LogicInst->getOpcode(), NewShift1, NewShift2); diff --git a/test/Transforms/InstCombine/shift-logic.ll b/test/Transforms/InstCombine/shift-logic.ll index 2c79a6e8cad..437bc1688be 100644 --- a/test/Transforms/InstCombine/shift-logic.ll +++ b/test/Transforms/InstCombine/shift-logic.ll @@ -16,9 +16,9 @@ define i8 @shl_and(i8 %x, i8 %y) { define <2 x i8> @shl_and_nonuniform(<2 x i8> %x, <2 x i8> %y) { ; CHECK-LABEL: @shl_and_nonuniform( -; CHECK-NEXT: [[SH0:%.*]] = shl <2 x i8> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[SH0]], [[Y:%.*]] -; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i8> [[R]], +; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i8> [[Y:%.*]], +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i8> [[TMP1]], [[TMP2]] ; CHECK-NEXT: ret <2 x i8> [[SH1]] ; %sh0 = shl <2 x i8> %x, @@ -45,9 +45,9 @@ define i16 @shl_or(i16 %x, i16 %py) { define <2 x i16> @shl_or_undef(<2 x i16> %x, <2 x i16> %py) { ; CHECK-LABEL: @shl_or_undef( ; CHECK-NEXT: [[Y:%.*]] = srem <2 x i16> [[PY:%.*]], -; CHECK-NEXT: [[SH0:%.*]] = shl <2 x i16> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[Y]], [[SH0]] -; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i16> [[R]], +; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i16> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i16> [[Y]], +; CHECK-NEXT: [[SH1:%.*]] = or <2 x i16> [[TMP1]], [[TMP2]] ; CHECK-NEXT: ret <2 x i16> [[SH1]] ; %y = srem <2 x i16> %py, ; thwart complexity-based canonicalization @@ -72,9 +72,9 @@ define i32 @shl_xor(i32 %x, i32 %y) { define <2 x i32> @shl_xor_nonuniform(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @shl_xor_nonuniform( -; CHECK-NEXT: [[SH0:%.*]] = shl <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[SH0]], [[Y:%.*]] -; CHECK-NEXT: [[SH1:%.*]] = shl <2 x i32> [[R]], +; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[SH1:%.*]] = xor <2 x i32> [[TMP1]], [[TMP2]] ; CHECK-NEXT: ret <2 x i32> [[SH1]] ; %sh0 = shl <2 x i32> %x, @@ -101,9 +101,9 @@ define i64 @lshr_and(i64 %x, i64 %py) { define <2 x i64> @lshr_and_undef(<2 x i64> %x, <2 x i64> %py) { ; CHECK-LABEL: @lshr_and_undef( ; CHECK-NEXT: [[Y:%.*]] = srem <2 x i64> [[PY:%.*]], -; CHECK-NEXT: [[SH0:%.*]] = lshr <2 x i64> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = and <2 x i64> [[Y]], [[SH0]] -; CHECK-NEXT: [[SH1:%.*]] = lshr <2 x i64> [[R]], +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i64> [[X:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = lshr <2 x i64> [[Y]], +; CHECK-NEXT: [[SH1:%.*]] = and <2 x i64> [[TMP1]], [[TMP2]] ; CHECK-NEXT: ret <2 x i64> [[SH1]] ; %y = srem <2 x i64> %py, ; thwart complexity-based canonicalization