[llvm] r317510 - [InstCombine] Pull shifts through a select plus binop with constant
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 7 09:37:27 PST 2017
I have committed a fix in Hexagon (r317592). Feel free to recommit this one.
-Krzysztof
On 11/6/2017 4:37 PM, Krzysztof Parzyszek via llvm-commits wrote:
> This may not be trivial for someone unfamiliar with the code. I can
> check this tomorrow.
>
> -Krzysztof
>
> On 11/6/2017 4:32 PM, Topper, Craig via llvm-commits wrote:
>> Thanks. I'll take a look.
>>
>> -----Original Message-----
>> From: hwennborg at google.com [mailto:hwennborg at google.com] On Behalf Of
>> Hans Wennborg
>> Sent: Monday, November 06, 2017 2:29 PM
>> To: Topper, Craig <craig.topper at intel.com>
>> Cc: llvm-commits <llvm-commits at lists.llvm.org>
>> Subject: Re: [llvm] r317510 - [InstCombine] Pull shifts through a
>> select plus binop with constant
>>
>> This broke the buildbots, e.g.
>> http://lab.llvm.org:8011/builders/clang-x86_64-debian-fast/builds/7386
>> It seems the CodeGen/Hexagon/loop-idiom/pmpy-mod.ll test hit some assert.
>>
>> I've reverted in r317518
>>
>> On Mon, Nov 6, 2017 at 1:07 PM, Craig Topper via llvm-commits
>> <llvm-commits at lists.llvm.org> wrote:
>>> Author: ctopper
>>> Date: Mon Nov 6 13:07:22 2017
>>> New Revision: 317510
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=317510&view=rev
>>> Log:
>>> [InstCombine] Pull shifts through a select plus binop with constant
>>>
>>> This pulls shifts through a select+binop with a constant where the
>>> select conditionally executes the binop. We already do this for just
>>> the binop, but not with the select.
>>>
>>> This can allow us to get the select closer to other selects to enable
>>> removing one.
>>>
>>> Differential Revision: https://reviews.llvm.org/D39222
>>>
>>> Modified:
>>> llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
>>> llvm/trunk/test/Transforms/InstCombine/shift.ll
>>>
>>> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=317510&r1=317509&r2=317510&view=diff
>>>
>>> ==============================================================================
>>>
>>> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
>>> (original)
>>> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Mon
>>> Nov 6 13:07:22 2017
>>> @@ -310,6 +310,40 @@ static Value *getShiftedValue(Value *V,
>>> }
>>> }
>>>
>>> +// If this is a bitwise operator or add with a constant RHS we might
>>> be able
>>> +// to pull it through a shift.
>>> +static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift,
>>> + BinaryOperator *BO,
>>> + const APInt &C) {
>>> + bool IsValid = true; // Valid only for And, Or Xor,
>>> + bool HighBitSet = false; // Transform ifhigh bit of constant set?
>>> +
>>> + switch (BO->getOpcode()) {
>>> + default: IsValid = false; break; // Do not perform transform!
>>> + case Instruction::Add:
>>> + IsValid = Shift.getOpcode() == Instruction::Shl;
>>> + break;
>>> + case Instruction::Or:
>>> + case Instruction::Xor:
>>> + HighBitSet = false;
>>> + break;
>>> + case Instruction::And:
>>> + HighBitSet = true;
>>> + break;
>>> + }
>>> +
>>> + // If this is a signed shift right, and the high bit is modified
>>> + // by the logical operation, do not perform the transformation.
>>> + // The HighBitSet boolean indicates the value of the high bit of
>>> + // the constant which would cause it to be modified for this
>>> + // operation.
>>> + //
>>> + if (IsValid && Shift.getOpcode() == Instruction::AShr)
>>> + IsValid = C.isNegative() == HighBitSet;
>>> +
>>> + return IsValid;
>>> +}
>>> +
>>> Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant
>>> *Op1,
>>> BinaryOperator &I) {
>>> bool isLeftShift = I.getOpcode() == Instruction::Shl;
>>> @@ -472,33 +506,7 @@ Instruction *InstCombiner::FoldShiftByCo
>>> // shift is the only use, we can pull it out of the shift.
>>> const APInt *Op0C;
>>> if (match(Op0BO->getOperand(1), m_APInt(Op0C))) {
>>> - bool isValid = true; // Valid only for And, Or, Xor
>>> - bool highBitSet = false; // Transform if high bit of
>>> constant set?
>>> -
>>> - switch (Op0BO->getOpcode()) {
>>> - default: isValid = false; break; // Do not perform transform!
>>> - case Instruction::Add:
>>> - isValid = isLeftShift;
>>> - break;
>>> - case Instruction::Or:
>>> - case Instruction::Xor:
>>> - highBitSet = false;
>>> - break;
>>> - case Instruction::And:
>>> - highBitSet = true;
>>> - break;
>>> - }
>>> -
>>> - // If this is a signed shift right, and the high bit is
>>> modified
>>> - // by the logical operation, do not perform the transformation.
>>> - // The highBitSet boolean indicates the value of the high
>>> bit of
>>> - // the constant which would cause it to be modified for this
>>> - // operation.
>>> - //
>>> - if (isValid && I.getOpcode() == Instruction::AShr)
>>> - isValid = Op0C->isNegative() == highBitSet;
>>> -
>>> - if (isValid) {
>>> + if (canShiftBinOpWithConstantRHS(I, Op0BO, *Op0C)) {
>>> Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
>>>
>>> cast<Constant>(Op0BO->getOperand(1)), Op1);
>>>
>>> @@ -525,6 +533,53 @@ Instruction *InstCombiner::FoldShiftByCo
>>> return BinaryOperator::CreateSub(NewRHS, NewShift);
>>> }
>>> }
>>> +
>>> + // If we have a select that conditionally executes some binary
>>> operator,
>>> + // see if we can pull it the select and operator through the shift.
>>> + //
>>> + // For example, turning:
>>> + // shl (select C, (add X, C1), X), C2
>>> + // Into:
>>> + // Y = shl X, C2
>>> + // select C, (add Y, C1 << C2), Y
>>> + Value *Cond;
>>> + BinaryOperator *TBO;
>>> + Value *FalseVal;
>>> + if (match(Op0, m_Select(m_Value(Cond), m_OneUse(m_BinOp(TBO)),
>>> + m_Value(FalseVal)))) {
>>> + const APInt *C;
>>> + if (!isa<Constant>(FalseVal) && TBO->getOperand(0) == FalseVal &&
>>> + match(TBO->getOperand(1), m_APInt(C)) &&
>>> + canShiftBinOpWithConstantRHS(I, TBO, *C)) {
>>> + Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
>>> +
>>> cast<Constant>(TBO->getOperand(1)), Op1);
>>> +
>>> + Value *NewShift =
>>> + Builder.CreateBinOp(I.getOpcode(), FalseVal, Op1);
>>> + Value *NewOp = Builder.CreateBinOp(TBO->getOpcode(), NewShift,
>>> + NewRHS);
>>> + return SelectInst::Create(Cond, NewOp, NewShift);
>>> + }
>>> + }
>>> +
>>> + BinaryOperator *FBO;
>>> + Value *TrueVal;
>>> + if (match(Op0, m_Select(m_Value(Cond), m_Value(TrueVal),
>>> + m_OneUse(m_BinOp(FBO))))) {
>>> + const APInt *C;
>>> + if (!isa<Constant>(TrueVal) && FBO->getOperand(0) == TrueVal &&
>>> + match(FBO->getOperand(1), m_APInt(C)) &&
>>> + canShiftBinOpWithConstantRHS(I, FBO, *C)) {
>>> + Constant *NewRHS = ConstantExpr::get(I.getOpcode(),
>>> +
>>> cast<Constant>(FBO->getOperand(1)), Op1);
>>> +
>>> + Value *NewShift =
>>> + Builder.CreateBinOp(I.getOpcode(), TrueVal, Op1);
>>> + Value *NewOp = Builder.CreateBinOp(FBO->getOpcode(), NewShift,
>>> + NewRHS);
>>> + return SelectInst::Create(Cond, NewShift, NewOp);
>>> + }
>>> + }
>>> }
>>>
>>> return nullptr;
>>>
>>> Modified: llvm/trunk/test/Transforms/InstCombine/shift.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/shift.ll?rev=317510&r1=317509&r2=317510&view=diff
>>>
>>> ==============================================================================
>>>
>>> --- llvm/trunk/test/Transforms/InstCombine/shift.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/shift.ll Mon Nov 6
>>> 13:07:22 2017
>>> @@ -1332,3 +1332,263 @@ define i7 @test65(i7 %a, i7 %b) {
>>> %y = and i7 %x, 1 ; this extracts the lsb which should be 0
>>> because we shifted an even number of bits and all even bits of the
>>> shift input are 0.
>>> ret i7 %y
>>> }
>>> +
>>> +define i32 @shl_select_add_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_add_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = add i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_add_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_add_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = add i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_and_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_and_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = and i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_and_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_and_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = and i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @lshr_select_and_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @lshr_select_and_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = and i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = lshr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @lshr_select_and_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @lshr_select_and_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = and i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = lshr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @ashr_select_and_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @ashr_select_and_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -1073741821
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = and i32 %x, 2147483655
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = ashr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @ashr_select_and_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @ashr_select_and_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], -1073741821
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = and i32 %x, 2147483655
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = ashr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_or_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_or_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = or i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_or_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_or_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = or i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @lshr_select_or_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @lshr_select_or_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = or i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = lshr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @lshr_select_or_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @lshr_select_or_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = or i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = lshr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @ashr_select_or_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @ashr_select_or_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = or i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = ashr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @ashr_select_or_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @ashr_select_or_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = or i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = ashr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_xor_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_xor_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = xor i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @shl_select_xor_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @shl_select_xor_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 14
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = xor i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = shl i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @lshr_select_xor_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @lshr_select_xor_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = xor i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = lshr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @lshr_select_xor_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @lshr_select_xor_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = xor i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = lshr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @ashr_select_xor_true(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @ashr_select_xor_true(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP2]], i32 [[TMP1]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = xor i32 %x, 7
>>> + %2 = select i1 %cond, i32 %1, i32 %x
>>> + %3 = ashr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>> +
>>> +define i32 @ashr_select_xor_false(i32 %x, i1 %cond) {
>>> +; CHECK-LABEL: @ashr_select_xor_false(
>>> +; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 [[X:%.*]], 1
>>> +; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 3
>>> +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[COND:%.*]], i32
>>> [[TMP1]], i32 [[TMP2]]
>>> +; CHECK-NEXT: ret i32 [[TMP3]]
>>> +;
>>> + %1 = xor i32 %x, 7
>>> + %2 = select i1 %cond, i32 %x, i32 %1
>>> + %3 = ashr i32 %2, 1
>>> + ret i32 %3
>>> +}
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
More information about the llvm-commits
mailing list