[llvm] r317510 - [InstCombine] Pull shifts through a select plus binop with constant

Topper, Craig via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 7 09:39:10 PST 2017


Thanks!

-----Original Message-----
From: Krzysztof Parzyszek [mailto:kparzysz at codeaurora.org] 
Sent: Tuesday, November 07, 2017 9:37 AM
To: Topper, Craig <craig.topper at intel.com>; Hans Wennborg <hans at chromium.org>
Cc: llvm-commits <llvm-commits at lists.llvm.org>
Subject: Re: [llvm] r317510 - [InstCombine] Pull shifts through a select plus binop with constant

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