[llvm] r296699 - [DAGCombiner] fold binops with constant into select-of-constants

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 2 09:46:56 PST 2017


This should be fixed with:
https://reviews.llvm.org/rL296768

Please let me know if you find any other problems. Thanks!

On Thu, Mar 2, 2017 at 9:00 AM, Sanjay Patel <spatel at rotateright.com> wrote:

> Thanks, Dave! Taking a look now. Sorry about the bug.
>
> On Thu, Mar 2, 2017 at 8:48 AM, David Green <David.Green at arm.com> wrote:
>
>> Hello,
>>
>>
>> I have an error for you. Compiled with:
>> clang -O3 -target aarch64-linux-gnu -mcpu=cortex-a57 -c reduce.c
>>
>> void d(unsigned a, long* b, long c) {
>>   long f = __builtin_neon_vcled_s64(a, c);
>>   long e = __builtin_neon_vshrd_n_u64(f, 20);
>>   f = 15281557956303287032 + e;
>>   *b = f;
>>   if (15281557956303287032 != c)
>>     g();
>> }
>>
>>
>> It's been fairly heavily creduced, so apologies for it's oddness. The
>> original was auto generated, so may not be a lot better. Let me know if you
>> need a larger version though.
>>
>>
>> clang-5.0: ../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1794:
>> llvm::SDValue {anonymous}::DAGCombiner::fold
>> BinOpIntoSelect(llvm::SDNode*): Assertion `(isConstantOrConstantVector(NewCT)
>> || isConstantFPBuildVectorOrConstantFP(NewCT)) && "Failed to constant
>> fold a binop with constant operands"' failed.
>> #0 0x00007f96c5604d69 llvm::sys::PrintStackTrace(llvm::raw_ostream&)
>> /work/llvm-git/build/../lib/Support/Unix/Signals.inc:402:0
>> #1 0x00007f96c5604dfa PrintStackTraceSignalHandler(void*)
>> /work/llvm-git/build/../lib/Support/Unix/Signals.inc:466:0
>> #2 0x00007f96c5603292 llvm::sys::RunSignalHandlers()
>> /work/llvm-git/build/../lib/Support/Signals.cpp:44:0
>> #3 0x00007f96c5604700 SignalHandler(int) /work/llvm-git/build/../lib/Su
>> pport/Unix/Signals.inc:256:0
>> #4 0x00007f96c2d9ecb0 (/lib/x86_64-linux-gnu/libc.so.6+0x36cb0)
>> #5 0x00007f96c2d9ec37 gsignal /build/eglibc-oGUzwX/eglibc-2.
>> 19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
>> #6 0x00007f96c2da2028 abort /build/eglibc-oGUzwX/eglibc-2.
>> 19/stdlib/abort.c:91:0
>> #7 0x00007f96c2d97bf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2.
>> 19/assert/assert.c:92:0
>> #8 0x00007f96c2d97ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
>> #9 0x00007f96c24eaacd (anonymous namespace)::DAGCombiner::foldBinOpIntoSelect(llvm::SDNode*)
>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1796:0
>> #10 0x00007f96c24eb07c (anonymous namespace)::DAGCombiner::visitADD(llvm::SDNode*)
>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1852:0
>> #11 0x00007f96c24e7f77 (anonymous namespace)::DAGCombiner::visit(llvm::SDNode*)
>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1385:0
>> #12 0x00007f96c24e87c3 (anonymous namespace)::DAGCombiner::combine(llvm::SDNode*)
>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1481:0
>> #13 0x00007f96c24e7ba4 (anonymous namespace)::DAGCombiner::Run(llvm::CombineLevel)
>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1335:0
>> #14 0x00007f96c254cac8 llvm::SelectionDAG::Combine(llvm::CombineLevel,
>> llvm::AAResults&, llvm::CodeGenOpt::Level) /work/llvm-git/build/../lib/Co
>> deGen/SelectionDAG/DAGCombiner.cpp:16196:0
>> #15 0x00007f96c27190a5 llvm::SelectionDAGISel::CodeGenAndEmitDAG()
>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/SelectionDA
>> GISel.cpp:807:0
>> #16 0x00007f96c2718861 llvm::SelectionDAGISel::Select
>> BasicBlock(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction,
>> true, false, void>, false, true>, llvm::ilist_iterator<llvm::ili
>> st_detail::node_options<llvm::Instruction, true, false, void>, false,
>> true>, bool&) /work/llvm-git/build/../lib/Co
>> deGen/SelectionDAG/SelectionDAGISel.cpp:728:0
>> #17 0x00007f96c271d65d llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function
>> const&) /work/llvm-git/build/../lib/CodeGen/SelectionDAG/SelectionDA
>> GISel.cpp:1694:0
>> #18 0x00007f96c2717679 llvm::SelectionDAGISel::runOnM
>> achineFunction(llvm::MachineFunction&) /work/llvm-git/build/../lib/Co
>> deGen/SelectionDAG/SelectionDAGISel.cpp:543:0
>> #19 0x00007f96cb575b86 (anonymous namespace)::AArch64DAGToDAGISe
>> l::runOnMachineFunction(llvm::MachineFunction&)
>> /work/llvm-git/build/../lib/Target/AArch64/AArch64ISelDAGToDAG.cpp:58:0
>> #20 0x00007f96c776a2c1 llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
>> /work/llvm-git/build/../lib/CodeGen/MachineFunctionPass.cpp:62:0
>> #21 0x00007f96c6ddac78 llvm::FPPassManager::runOnFunction(llvm::Function&)
>> /work/llvm-git/build/../lib/IR/LegacyPassManager.cpp:1513:0
>> #22 0x00007f96c6ddae0b llvm::FPPassManager::runOnModule(llvm::Module&)
>> /work/llvm-git/build/../lib/IR/LegacyPassManager.cpp:1534:0
>> #23 0x00007f96c6ddb1a6 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&)
>> /work/llvm-git/build/../lib/IR/LegacyPassManager.cpp:1590:0
>> #24 0x00007f96c6ddb8f6 llvm::legacy::PassManagerImpl::run(llvm::Module&)
>> /work/llvm-git/build/../lib/IR/LegacyPassManager.cpp:1693:0
>> #25 0x00007f96c6ddbb37 llvm::legacy::PassManager::run(llvm::Module&)
>> /work/llvm-git/build/../lib/IR/LegacyPassManager.cpp:1725:0
>> #26 0x00007f96c3e6dec5 (anonymous namespace)::EmitAssemblyHelper
>> ::EmitAssembly(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream,
>> std::default_delete<llvm::raw_pwrite_stream> >)
>> /work/llvm-git/build/../tools/clang/lib/CodeGen/BackendUtil.cpp:730:0
>> #27 0x00007f96c3e6f886 clang::EmitBackendOutput(clang::DiagnosticsEngine&,
>> clang::HeaderSearchOptions const&, clang::CodeGenOptions const&,
>> clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout
>> const&, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream,
>> std::default_delete<llvm::raw_pwrite_stream> >)
>> /work/llvm-git/build/../tools/clang/lib/CodeGen/BackendUtil.cpp:999:0
>> #28 0x00007f96c418381d clang::BackendConsumer::Handle
>> TranslationUnit(clang::ASTContext&) /work/llvm-git/build/../tools/
>> clang/lib/CodeGen/CodeGenAction.cpp:243:0
>> #29 0x00007f96bf743d7b clang::ParseAST(clang::Sema&, bool, bool)
>> /work/llvm-git/build/../tools/clang/lib/Parse/ParseAST.cpp:161:0
>> #30 0x00007f96c382b3a4 clang::ASTFrontendAction::ExecuteAction()
>> /work/llvm-git/build/../tools/clang/lib/Frontend/FrontendAction.cpp:569:0
>> #31 0x00007f96c4180899 clang::CodeGenAction::ExecuteAction()
>> /work/llvm-git/build/../tools/clang/lib/CodeGen/CodeGenAction.cpp:973:0
>> #32 0x00007f96c382ae49 clang::FrontendAction::Execute()
>> /work/llvm-git/build/../tools/clang/lib/Frontend/FrontendAction.cpp:472:0
>> #33 0x00007f96c37bff23 clang::CompilerInstance::Execu
>> teAction(clang::FrontendAction&) /work/llvm-git/build/../tools/
>> clang/lib/Frontend/CompilerInstance.cpp:951:0
>> #34 0x00007f96c34d5d2a clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
>> /work/llvm-git/build/../tools/clang/lib/FrontendTool/Execute
>> CompilerInvocation.cpp:249:0
>> #35 0x000000000044a53f cc1_main(llvm::ArrayRef<char const*>, char const*,
>> void*) /work/llvm-git/build/../tools/clang/tools/driver/cc1_main.cp
>> p:221:0
>> #36 0x000000000044059c ExecuteCC1Tool(llvm::ArrayRef<char const*>,
>> llvm::StringRef) /work/llvm-git/build/../tools/
>> clang/tools/driver/driver.cpp:299:0
>> #37 0x000000000044119a main /work/llvm-git/build/../tools/
>> clang/tools/driver/driver.cpp:380:0
>> #38 0x00007f96c2d89f45 __libc_start_main /build/eglibc-oGUzwX/eglibc-2.
>> 19/csu/libc-start.c:321:0
>> #39 0x000000000043e009 _start (/work/llvm-git/build/bin/clan
>> g-5.0+0x43e009)
>> Stack dump:
>> 0. Program arguments: /work/llvm-git/build/bin/clang-5.0 -cc1 -triple
>> aarch64--linux-gnu -emit-obj -disable-free -main-file-name reduce.c
>> -mrelocation-model static -mthread-model posix -mdisable-fp-elim
>> -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array
>> -target-cpu cortex-a57 -target-feature +neon -target-feature +crc
>> -target-feature +crypto -target-abi aapcs -dwarf-column-info
>> -debugger-tuning=gdb -coverage-notes-file /work/tmp/testing/emp/reduce/reduce.gcno
>> -resource-dir /work/llvm-git/build/lib/clang/5.0.0 -internal-isystem
>> /usr/local/include -internal-isystem /work/llvm-git/build/lib/clang/5.0.0/include
>> -internal-externc-isystem /include -internal-externc-isystem /usr/include
>> -O3 -fdebug-compilation-dir /work/tmp/testing/emp/reduce -ferror-limit 19
>> -fmessage-length 102 -fallow-half-arguments-and-returns -fno-signed-char
>> -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics
>> -vectorize-loops -vectorize-slp -o reduce.o -x c reduce.c
>> 1. <eof> parser at end of file
>> 2. Code generation
>> 3. Running pass 'Function Pass Manager' on module 'reduce.c'.
>> 4. Running pass 'AArch64 Instruction Selection' on function '@d'
>> clang-5.0: error: unable to execute command: Aborted (core dumped)
>> clang-5.0: error: clang frontend command failed due to signal (use -v to
>> see invocation)
>> clang version 5.0.0 (http://llvm.org/git/clang.git
>> 77b000e5f923dc575e614259c3506ed5bc855297) (http://llvm.org/git/llvm.git
>> 4f2d8229c1c2152df50669701f0fe44f5e412fa3)
>> Target: aarch64--linux-gnu
>> Thread model: posix
>> InstalledDir: /work/llvm-git/build/bin
>> clang-5.0: note: diagnostic msg: PLEASE submit a bug report to
>> http://llvm.org/bugs/ and include the crash backtrace, preprocessed
>> source, and associated run script.
>> clang-5.0: note: diagnostic msg:
>> ********************
>>
>> PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
>> Preprocessed source(s) and associated run script(s) are located at:
>> clang-5.0: note: diagnostic msg: /tmp/reduce-d3ed6e.c
>> clang-5.0: note: diagnostic msg: /tmp/reduce-d3ed6e.sh
>> clang-5.0: note: diagnostic msg:
>>
>> ********************
>>
>>
>>
>> Cheers
>> Dave
>>
>> ------------------------------
>> *From:* llvm-commits <llvm-commits-bounces at lists.llvm.org> on behalf of
>> Sanjay Patel via llvm-commits <llvm-commits at lists.llvm.org>
>> *Sent:* 01 March 2017 22:51
>> *To:* llvm-commits at lists.llvm.org
>> *Subject:* [llvm] r296699 - [DAGCombiner] fold binops with constant into
>> select-of-constants
>>
>> Author: spatel
>> Date: Wed Mar  1 16:51:31 2017
>> New Revision: 296699
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=296699&view=rev
>> Log:
>> [DAGCombiner] fold binops with constant into select-of-constants
>>
>> This is part of the ongoing attempt to improve select codegen for all
>> targets and select
>> canonicalization in IR (see D24480 for more background). The transform is
>> a subset of what
>> is done in InstCombine's FoldOpIntoSelect().
>>
>> I first noticed a regression in the x86 avx512-insert-extract.ll tests
>> with a patch that
>> hopes to convert more selects to basic math ops. This appears to be a
>> general missing DAG
>> transform though, so I added tests for all standard binops in rL296621
>> (PowerPC was chosen semi-randomly; it has scripted FileCheck support, but
>> so do ARM and x86).
>>
>> The poor output for "sel_constants_shl_constant" is tracked with:
>> https://bugs.llvm.org/show_bug.cgi?id=32105
>>
>> Differential Revision: https://reviews.llvm.org/D30502
>>
>> Modified:
>>     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>>     llvm/trunk/test/CodeGen/ARM/select_xform.ll
>>     llvm/trunk/test/CodeGen/PowerPC/select_const.ll
>>     llvm/trunk/test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll
>>     llvm/trunk/test/CodeGen/X86/avx512-insert-extract.ll
>>     llvm/trunk/test/CodeGen/X86/select_const.ll
>>     llvm/trunk/test/CodeGen/X86/setcc.ll
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
>> SelectionDAG/DAGCombiner.cpp?rev=296699&r1=296698&r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Mar  1
>> 16:51:31 2017
>> @@ -337,6 +337,7 @@ namespace {
>>      SDValue visitShiftByConstant(SDNode *N, ConstantSDNode *Amt);
>>
>>      SDValue foldSelectOfConstants(SDNode *N);
>> +    SDValue foldBinOpIntoSelect(SDNode *BO);
>>      bool SimplifySelectOps(SDNode *SELECT, SDValue LHS, SDValue RHS);
>>      SDValue SimplifyBinOpWithSameOpcodeHands(SDNode *N);
>>      SDValue SimplifySelect(const SDLoc &DL, SDValue N0, SDValue N1,
>> SDValue N2);
>> @@ -1747,6 +1748,59 @@ static ConstantSDNode *getAsNonOpaqueCon
>>    return Const != nullptr && !Const->isOpaque() ? Const : nullptr;
>>  }
>>
>> +SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
>> +  auto BinOpcode = BO->getOpcode();
>> +  assert((BinOpcode == ISD::ADD || BinOpcode == ISD::SUB ||
>> +          BinOpcode == ISD::MUL || BinOpcode == ISD::SDIV ||
>> +          BinOpcode == ISD::UDIV || BinOpcode == ISD::SREM ||
>> +          BinOpcode == ISD::UREM || BinOpcode == ISD::AND ||
>> +          BinOpcode == ISD::OR || BinOpcode == ISD::XOR ||
>> +          BinOpcode == ISD::SHL || BinOpcode == ISD::SRL ||
>> +          BinOpcode == ISD::SRA || BinOpcode == ISD::FADD ||
>> +          BinOpcode == ISD::FSUB || BinOpcode == ISD::FMUL ||
>> +          BinOpcode == ISD::FDIV || BinOpcode == ISD::FREM) &&
>> +         "Unexpected binary operator");
>> +
>> +  SDValue C1 = BO->getOperand(1);
>> +  if (!isConstantOrConstantVector(C1) &&
>> +      !isConstantFPBuildVectorOrConstantFP(C1))
>> +    return SDValue();
>> +
>> +  // Don't do this unless the old select is going away. We want to
>> eliminate the
>> +  // binary operator, not replace a binop with a select.
>> +  // TODO: Handle ISD::SELECT_CC.
>> +  SDValue Sel = BO->getOperand(0);
>> +  if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse())
>> +    return SDValue();
>> +
>> +  SDValue CT = Sel.getOperand(1);
>> +  if (!isConstantOrConstantVector(CT) &&
>> +      !isConstantFPBuildVectorOrConstantFP(CT))
>> +    return SDValue();
>> +
>> +  SDValue CF = Sel.getOperand(2);
>> +  if (!isConstantOrConstantVector(CF) &&
>> +      !isConstantFPBuildVectorOrConstantFP(CF))
>> +    return SDValue();
>> +
>> +  // We have a select-of-constants followed by a binary operator with a
>> +  // constant. Eliminate the binop by pulling the constant math into the
>> select.
>> +  // Example: add (select Cond, CT, CF), C1 --> select Cond, CT + C1, CF
>> + C1
>> +  EVT VT = Sel.getValueType();
>> +  SDLoc DL(Sel);
>> +  SDValue NewCT = DAG.getNode(BinOpcode, DL, VT, CT, C1);
>> +  assert((isConstantOrConstantVector(NewCT) ||
>> +          isConstantFPBuildVectorOrConstantFP(NewCT)) &&
>> +         "Failed to constant fold a binop with constant operands");
>> +
>> +  SDValue NewCF = DAG.getNode(BinOpcode, DL, VT, CF, C1);
>> +  assert((isConstantOrConstantVector(NewCF) ||
>> +          isConstantFPBuildVectorOrConstantFP(NewCF)) &&
>> +         "Failed to constant fold a binop with constant operands");
>> +
>> +  return DAG.getSelect(DL, VT, Sel.getOperand(0), NewCT, NewCF);
>> +}
>> +
>>  SDValue DAGCombiner::visitADD(SDNode *N) {
>>    SDValue N0 = N->getOperand(0);
>>    SDValue N1 = N->getOperand(1);
>> @@ -1795,6 +1849,9 @@ SDValue DAGCombiner::visitADD(SDNode *N)
>>        }
>>    }
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // reassociate add
>>    if (SDValue RADD = ReassociateOps(ISD::ADD, DL, N0, N1))
>>      return RADD;
>> @@ -1999,6 +2056,9 @@ SDValue DAGCombiner::visitSUB(SDNode *N)
>>                                        N1.getNode());
>>    }
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    ConstantSDNode *N1C = getAsNonOpaqueConstant(N1);
>>
>>    // fold (sub x, c) -> (add x, -c)
>> @@ -2210,6 +2270,10 @@ SDValue DAGCombiner::visitMUL(SDNode *N)
>>    // fold (mul x, 1) -> x
>>    if (N1IsConst && ConstValue1 == 1 && IsFullSplat)
>>      return N0;
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // fold (mul x, -1) -> 0-x
>>    if (N1IsConst && ConstValue1.isAllOnesValue()) {
>>      SDLoc DL(N);
>> @@ -2401,6 +2465,9 @@ SDValue DAGCombiner::visitSDIV(SDNode *N
>>      return DAG.getNode(ISD::SUB, DL, VT,
>>                         DAG.getConstant(0, DL, VT), N0);
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // If we know the sign bits of both operands are zero, strength reduce
>> to a
>>    // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2
>>    if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
>> @@ -2493,6 +2560,9 @@ SDValue DAGCombiner::visitUDIV(SDNode *N
>>                                                      N0C, N1C))
>>        return Folded;
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // fold (udiv x, (1 << c)) -> x >>u c
>>    if (isConstantOrConstantVector(N1, /*NoOpaques*/ true) &&
>>        DAG.isKnownToBeAPowerOfTwo(N1)) {
>> @@ -2561,6 +2631,9 @@ SDValue DAGCombiner::visitREM(SDNode *N)
>>      if (SDValue Folded = DAG.FoldConstantArithmetic(Opcode, DL, VT,
>> N0C, N1C))
>>        return Folded;
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    if (isSigned) {
>>      // If we know the sign bits of both operands are zero, strength
>> reduce to a
>>      // urem instead.  Handles (X & 0x0FFFFFFF) %s 16 -> X&15
>> @@ -3267,6 +3340,10 @@ SDValue DAGCombiner::visitAND(SDNode *N)
>>    if (N1C && DAG.MaskedValueIsZero(SDValue(N, 0),
>>                                     APInt::getAllOnesValue(BitWidth)))
>>      return DAG.getConstant(0, SDLoc(N), VT);
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // reassociate and
>>    if (SDValue RAND = ReassociateOps(ISD::AND, SDLoc(N), N0, N1))
>>      return RAND;
>> @@ -4008,6 +4085,10 @@ SDValue DAGCombiner::visitOR(SDNode *N)
>>    // fold (or x, -1) -> -1
>>    if (isAllOnesConstant(N1))
>>      return N1;
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // fold (or x, c) -> c iff (x & ~c) == 0
>>    if (N1C && DAG.MaskedValueIsZero(N0, ~N1C->getAPIntValue()))
>>      return N1;
>> @@ -4753,6 +4834,10 @@ SDValue DAGCombiner::visitXOR(SDNode *N)
>>    // fold (xor x, 0) -> x
>>    if (isNullConstant(N1))
>>      return N0;
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // reassociate xor
>>    if (SDValue RXOR = ReassociateOps(ISD::XOR, SDLoc(N), N0, N1))
>>      return RXOR;
>> @@ -5040,6 +5125,10 @@ SDValue DAGCombiner::visitSHL(SDNode *N)
>>    // fold (shl undef, x) -> 0
>>    if (N0.isUndef())
>>      return DAG.getConstant(0, SDLoc(N), VT);
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // if (shl x, c) is known to be zero, return 0
>>    if (DAG.MaskedValueIsZero(SDValue(N, 0),
>>                              APInt::getAllOnesValue(OpSizeInBits)))
>> @@ -5243,6 +5332,10 @@ SDValue DAGCombiner::visitSRA(SDNode *N)
>>    // fold (sra x, 0) -> x
>>    if (N1C && N1C->isNullValue())
>>      return N0;
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // fold (sra (shl x, c1), c1) -> sext_inreg for some c1 and target
>> supports
>>    // sext_inreg.
>>    if (N1C && N0.getOpcode() == ISD::SHL && N1 == N0.getOperand(1)) {
>> @@ -5390,6 +5483,10 @@ SDValue DAGCombiner::visitSRL(SDNode *N)
>>    // fold (srl x, 0) -> x
>>    if (N1C && N1C->isNullValue())
>>      return N0;
>> +
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // if (srl x, c) is known to be zero, return 0
>>    if (N1C && DAG.MaskedValueIsZero(SDValue(N, 0),
>>                                     APInt::getAllOnesValue(OpSizeI
>> nBits)))
>> @@ -9064,6 +9161,9 @@ SDValue DAGCombiner::visitFADD(SDNode *N
>>    if (N0CFP && !N1CFP)
>>      return DAG.getNode(ISD::FADD, DL, VT, N1, N0, Flags);
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // fold (fadd A, (fneg B)) -> (fsub A, B)
>>    if ((!LegalOperations || TLI.isOperationLegalOrCustom(ISD::FSUB, VT))
>> &&
>>        isNegatibleForFree(N1, LegalOperations, TLI, &Options) == 2)
>> @@ -9211,6 +9311,9 @@ SDValue DAGCombiner::visitFSUB(SDNode *N
>>    if (N0CFP && N1CFP)
>>      return DAG.getNode(ISD::FSUB, DL, VT, N0, N1, Flags);
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    // fold (fsub A, (fneg B)) -> (fadd A, B)
>>    if (isNegatibleForFree(N1, LegalOperations, TLI, &Options))
>>      return DAG.getNode(ISD::FADD, DL, VT, N0,
>> @@ -9290,6 +9393,9 @@ SDValue DAGCombiner::visitFMUL(SDNode *N
>>    if (N1CFP && N1CFP->isExactlyValue(1.0))
>>      return N0;
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    if (Options.UnsafeFPMath) {
>>      // fold (fmul A, 0) -> 0
>>      if (N1CFP && N1CFP->isZero())
>> @@ -9544,6 +9650,9 @@ SDValue DAGCombiner::visitFDIV(SDNode *N
>>    if (N0CFP && N1CFP)
>>      return DAG.getNode(ISD::FDIV, SDLoc(N), VT, N0, N1, Flags);
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    if (Options.UnsafeFPMath) {
>>      // fold (fdiv X, c2) -> fmul X, 1/c2 if losing precision is
>> acceptable.
>>      if (N1CFP) {
>> @@ -9647,6 +9756,9 @@ SDValue DAGCombiner::visitFREM(SDNode *N
>>      return DAG.getNode(ISD::FREM, SDLoc(N), VT, N0, N1,
>>                         &cast<BinaryWithFlagsSDNode>(N)->Flags);
>>
>> +  if (SDValue NewSel = foldBinOpIntoSelect(N))
>> +    return NewSel;
>> +
>>    return SDValue();
>>  }
>>
>>
>> Modified: llvm/trunk/test/CodeGen/ARM/select_xform.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/
>> ARM/select_xform.ll?rev=296699&r1=296698&r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/CodeGen/ARM/select_xform.ll (original)
>> +++ llvm/trunk/test/CodeGen/ARM/select_xform.ll Wed Mar  1 16:51:31 2017
>> @@ -223,21 +223,19 @@ entry:
>>    ret i32 %add
>>  }
>>
>> -; Do not fold the xor into the select
>> +; Fold the xor into the select.
>>  define i32 @t15(i32 %p) {
>>  entry:
>>  ; ARM-LABEL: t15:
>> -; ARM: mov     [[REG:r[0-9]+]], #2
>> +; ARM: mov     [[REG:r[0-9]+]], #3
>>  ; ARM: cmp     r0, #8
>> -; ARM: movwgt  [[REG:r[0-9]+]], #1
>> -; ARM: eor     r0, [[REG:r[0-9]+]], #1
>> +; ARM: movwgt  [[REG:r[0-9]+]], #0
>>
>>  ; T2-LABEL: t15:
>> -; T2: movs    [[REG:r[0-9]+]], #2
>> +; T2: movs    [[REG:r[0-9]+]], #3
>>  ; T2: cmp     [[REG:r[0-9]+]], #8
>>  ; T2: it      gt
>> -; T2: movgt   [[REG:r[0-9]+]], #1
>> -; T2: eor     r0, [[REG:r[0-9]+]], #1
>> +; T2: movgt   [[REG:r[0-9]+]], #0
>>    %cmp = icmp sgt i32 %p, 8
>>    %a = select i1 %cmp, i32 1, i32 2
>>    %xor = xor i32 %a, 1
>>
>> Modified: llvm/trunk/test/CodeGen/PowerPC/select_const.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/
>> PowerPC/select_const.ll?rev=296699&r1=296698&r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/CodeGen/PowerPC/select_const.ll (original)
>> +++ llvm/trunk/test/CodeGen/PowerPC/select_const.ll Wed Mar  1 16:51:31
>> 2017
>> @@ -435,23 +435,20 @@ define i8 @sel_constants_add_constant(i1
>>  ; ISEL-LABEL: sel_constants_add_constant:
>>  ; ISEL:       # BB#0:
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> +; ISEL-NEXT:    li 4, 1
>> +; ISEL-NEXT:    li 3, 28
>>  ; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    addi 3, 3, 5
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_add_constant:
>>  ; NO_ISEL:       # BB#0:
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> +; NO_ISEL-NEXT:    li 4, 1
>> +; NO_ISEL-NEXT:    li 3, 28
>>  ; NO_ISEL-NEXT:    bc 12, 1, .LBB21_1
>> -; NO_ISEL-NEXT:    b .LBB21_2
>> +; NO_ISEL-NEXT:    blr
>>  ; NO_ISEL-NEXT:  .LBB21_1:
>>  ; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB21_2:
>> -; NO_ISEL-NEXT:    addi 3, 3, 5
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = add i8 %sel, 5
>> @@ -461,24 +458,24 @@ define i8 @sel_constants_add_constant(i1
>>  define i8 @sel_constants_sub_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_sub_constant:
>>  ; ISEL:       # BB#0:
>> +; ISEL-NEXT:    li 4, 0
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> -; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    addi 3, 3, -5
>> +; ISEL-NEXT:    oris 3, 4, 65535
>> +; ISEL-NEXT:    li 4, 18
>> +; ISEL-NEXT:    ori 3, 3, 65527
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_sub_constant:
>>  ; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    li 4, 0
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB22_1
>> -; NO_ISEL-NEXT:    b .LBB22_2
>> -; NO_ISEL-NEXT:  .LBB22_1:
>> -; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB22_2:
>> -; NO_ISEL-NEXT:    addi 3, 3, -5
>> +; NO_ISEL-NEXT:    oris 3, 4, 65535
>> +; NO_ISEL-NEXT:    li 4, 18
>> +; NO_ISEL-NEXT:    ori 3, 3, 65527
>> +; NO_ISEL-NEXT:    bclr 12, 1, 0
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = sub i8 %sel, 5
>> @@ -488,24 +485,24 @@ define i8 @sel_constants_sub_constant(i1
>>  define i8 @sel_constants_mul_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_mul_constant:
>>  ; ISEL:       # BB#0:
>> +; ISEL-NEXT:    lis 4, 16383
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> -; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    mulli 3, 3, 5
>> +; ISEL-NEXT:    ori 3, 4, 65531
>> +; ISEL-NEXT:    li 4, 115
>> +; ISEL-NEXT:    sldi 3, 3, 2
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_mul_constant:
>>  ; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    lis 4, 16383
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB23_1
>> -; NO_ISEL-NEXT:    b .LBB23_2
>> -; NO_ISEL-NEXT:  .LBB23_1:
>> -; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB23_2:
>> -; NO_ISEL-NEXT:    mulli 3, 3, 5
>> +; NO_ISEL-NEXT:    ori 3, 4, 65531
>> +; NO_ISEL-NEXT:    li 4, 115
>> +; NO_ISEL-NEXT:    sldi 3, 3, 2
>> +; NO_ISEL-NEXT:    bclr 12, 1, 0
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = mul i8 %sel, 5
>> @@ -516,33 +513,18 @@ define i8 @sel_constants_sdiv_constant(i
>>  ; ISEL-LABEL: sel_constants_sdiv_constant:
>>  ; ISEL:       # BB#0:
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    lis 5, 26214
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> -; ISEL-NEXT:    ori 12, 5, 26215
>> -; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    mulld 3, 3, 12
>> -; ISEL-NEXT:    rldicl 4, 3, 1, 63
>> -; ISEL-NEXT:    sradi 3, 3, 33
>> -; ISEL-NEXT:    add 3, 3, 4
>> +; ISEL-NEXT:    li 3, 4
>> +; ISEL-NEXT:    isel 3, 0, 3, 1
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_sdiv_constant:
>>  ; NO_ISEL:       # BB#0:
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    lis 5, 26214
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> -; NO_ISEL-NEXT:    ori 12, 5, 26215
>> +; NO_ISEL-NEXT:    li 3, 4
>>  ; NO_ISEL-NEXT:    bc 12, 1, .LBB24_1
>> -; NO_ISEL-NEXT:    b .LBB24_2
>> +; NO_ISEL-NEXT:    blr
>>  ; NO_ISEL-NEXT:  .LBB24_1:
>> -; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB24_2:
>> -; NO_ISEL-NEXT:    mulld 3, 3, 12
>> -; NO_ISEL-NEXT:    rldicl 4, 3, 1, 63
>> -; NO_ISEL-NEXT:    sradi 3, 3, 33
>> -; NO_ISEL-NEXT:    add 3, 3, 4
>> +; NO_ISEL-NEXT:    addi 3, 0, 0
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = sdiv i8 %sel, 5
>> @@ -552,38 +534,21 @@ define i8 @sel_constants_sdiv_constant(i
>>  define i8 @sel_constants_udiv_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_udiv_constant:
>>  ; ISEL:       # BB#0:
>> -; ISEL-NEXT:    lis 4, 16383
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 5, 0
>> -; ISEL-NEXT:    ori 3, 4, 65535
>> -; ISEL-NEXT:    li 4, 23
>> -; ISEL-NEXT:    oris 12, 5, 52428
>> -; ISEL-NEXT:    sldi 3, 3, 2
>> -; ISEL-NEXT:    isel 3, 3, 4, 1
>> -; ISEL-NEXT:    ori 4, 12, 52429
>> -; ISEL-NEXT:    clrldi 3, 3, 56
>> -; ISEL-NEXT:    mulld 3, 3, 4
>> -; ISEL-NEXT:    rldicl 3, 3, 30, 34
>> +; ISEL-NEXT:    li 4, 50
>> +; ISEL-NEXT:    li 3, 4
>> +; ISEL-NEXT:    isel 3, 4, 3, 1
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_udiv_constant:
>>  ; NO_ISEL:       # BB#0:
>> -; NO_ISEL-NEXT:    lis 4, 16383
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 5, 0
>> -; NO_ISEL-NEXT:    ori 3, 4, 65535
>> -; NO_ISEL-NEXT:    li 4, 23
>> -; NO_ISEL-NEXT:    oris 12, 5, 52428
>> -; NO_ISEL-NEXT:    sldi 3, 3, 2
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB25_2
>> -; NO_ISEL-NEXT:  # BB#1:
>> -; NO_ISEL-NEXT:    ori 3, 4, 0
>> -; NO_ISEL-NEXT:    b .LBB25_2
>> -; NO_ISEL-NEXT:  .LBB25_2:
>> -; NO_ISEL-NEXT:    ori 4, 12, 52429
>> -; NO_ISEL-NEXT:    clrldi 3, 3, 56
>> -; NO_ISEL-NEXT:    mulld 3, 3, 4
>> -; NO_ISEL-NEXT:    rldicl 3, 3, 30, 34
>> +; NO_ISEL-NEXT:    li 4, 50
>> +; NO_ISEL-NEXT:    li 3, 4
>> +; NO_ISEL-NEXT:    bc 12, 1, .LBB25_1
>> +; NO_ISEL-NEXT:    blr
>> +; NO_ISEL-NEXT:  .LBB25_1:
>> +; NO_ISEL-NEXT:    addi 3, 4, 0
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = udiv i8 %sel, 5
>> @@ -593,40 +558,24 @@ define i8 @sel_constants_udiv_constant(i
>>  define i8 @sel_constants_srem_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_srem_constant:
>>  ; ISEL:       # BB#0:
>> +; ISEL-NEXT:    lis 4, 16383
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    lis 12, 26214
>> -; ISEL-NEXT:    li 3, 23
>> -; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    ori 4, 12, 26215
>> -; ISEL-NEXT:    extsw 3, 3
>> -; ISEL-NEXT:    mulld 4, 3, 4
>> -; ISEL-NEXT:    rldicl 5, 4, 1, 63
>> -; ISEL-NEXT:    sradi 4, 4, 33
>> -; ISEL-NEXT:    add 4, 4, 5
>> -; ISEL-NEXT:    mulli 4, 4, 5
>> -; ISEL-NEXT:    subf 3, 4, 3
>> +; ISEL-NEXT:    ori 3, 4, 65535
>> +; ISEL-NEXT:    li 4, 3
>> +; ISEL-NEXT:    sldi 3, 3, 2
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_srem_constant:
>>  ; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    lis 4, 16383
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    lis 12, 26214
>> -; NO_ISEL-NEXT:    li 3, 23
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB26_1
>> -; NO_ISEL-NEXT:    b .LBB26_2
>> -; NO_ISEL-NEXT:  .LBB26_1:
>> -; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB26_2:
>> -; NO_ISEL-NEXT:    ori 4, 12, 26215
>> -; NO_ISEL-NEXT:    extsw 3, 3
>> -; NO_ISEL-NEXT:    mulld 4, 3, 4
>> -; NO_ISEL-NEXT:    rldicl 5, 4, 1, 63
>> -; NO_ISEL-NEXT:    sradi 4, 4, 33
>> -; NO_ISEL-NEXT:    add 4, 4, 5
>> -; NO_ISEL-NEXT:    mulli 4, 4, 5
>> -; NO_ISEL-NEXT:    subf 3, 4, 3
>> +; NO_ISEL-NEXT:    ori 3, 4, 65535
>> +; NO_ISEL-NEXT:    li 4, 3
>> +; NO_ISEL-NEXT:    sldi 3, 3, 2
>> +; NO_ISEL-NEXT:    bclr 12, 1, 0
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = srem i8 %sel, 5
>> @@ -637,39 +586,20 @@ define i8 @sel_constants_urem_constant(i
>>  ; ISEL-LABEL: sel_constants_urem_constant:
>>  ; ISEL:       # BB#0:
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 12, 0
>> -; ISEL-NEXT:    li 3, 23
>> +; ISEL-NEXT:    li 4, 2
>> +; ISEL-NEXT:    li 3, 3
>>  ; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    oris 4, 12, 52428
>> -; ISEL-NEXT:    rlwinm 3, 3, 0, 24, 31
>> -; ISEL-NEXT:    ori 4, 4, 52429
>> -; ISEL-NEXT:    clrldi 5, 3, 32
>> -; ISEL-NEXT:    mulld 4, 5, 4
>> -; ISEL-NEXT:    rldicl 4, 4, 30, 34
>> -; ISEL-NEXT:    mulli 4, 4, 5
>> -; ISEL-NEXT:    subf 3, 4, 3
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_urem_constant:
>>  ; NO_ISEL:       # BB#0:
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 12, 0
>> -; NO_ISEL-NEXT:    li 3, 23
>> +; NO_ISEL-NEXT:    li 4, 2
>> +; NO_ISEL-NEXT:    li 3, 3
>>  ; NO_ISEL-NEXT:    bc 12, 1, .LBB27_1
>> -; NO_ISEL-NEXT:    b .LBB27_2
>> +; NO_ISEL-NEXT:    blr
>>  ; NO_ISEL-NEXT:  .LBB27_1:
>>  ; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB27_2:
>> -; NO_ISEL-NEXT:    oris 4, 12, 52428
>> -; NO_ISEL-NEXT:    rlwinm 3, 3, 0, 24, 31
>> -; NO_ISEL-NEXT:    ori 4, 4, 52429
>> -; NO_ISEL-NEXT:    clrldi 5, 3, 32
>> -; NO_ISEL-NEXT:    mulld 4, 5, 4
>> -; NO_ISEL-NEXT:    rldicl 4, 4, 30, 34
>> -; NO_ISEL-NEXT:    mulli 4, 4, 5
>> -; NO_ISEL-NEXT:    subf 3, 4, 3
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = urem i8 %sel, 5
>> @@ -679,28 +609,21 @@ define i8 @sel_constants_urem_constant(i
>>  define i8 @sel_constants_and_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_and_constant:
>>  ; ISEL:       # BB#0:
>> -; ISEL-NEXT:    lis 4, 16383
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    ori 3, 4, 65535
>> -; ISEL-NEXT:    li 4, 23
>> -; ISEL-NEXT:    sldi 3, 3, 2
>> -; ISEL-NEXT:    isel 3, 3, 4, 1
>> -; ISEL-NEXT:    andi. 3, 3, 5
>> +; ISEL-NEXT:    li 4, 4
>> +; ISEL-NEXT:    li 3, 5
>> +; ISEL-NEXT:    isel 3, 4, 3, 1
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_and_constant:
>>  ; NO_ISEL:       # BB#0:
>> -; NO_ISEL-NEXT:    lis 4, 16383
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    ori 3, 4, 65535
>> -; NO_ISEL-NEXT:    li 4, 23
>> -; NO_ISEL-NEXT:    sldi 3, 3, 2
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB28_2
>> -; NO_ISEL-NEXT:  # BB#1:
>> -; NO_ISEL-NEXT:    ori 3, 4, 0
>> -; NO_ISEL-NEXT:    b .LBB28_2
>> -; NO_ISEL-NEXT:  .LBB28_2:
>> -; NO_ISEL-NEXT:    andi. 3, 3, 5
>> +; NO_ISEL-NEXT:    li 4, 4
>> +; NO_ISEL-NEXT:    li 3, 5
>> +; NO_ISEL-NEXT:    bc 12, 1, .LBB28_1
>> +; NO_ISEL-NEXT:    blr
>> +; NO_ISEL-NEXT:  .LBB28_1:
>> +; NO_ISEL-NEXT:    addi 3, 4, 0
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = and i8 %sel, 5
>> @@ -710,28 +633,24 @@ define i8 @sel_constants_and_constant(i1
>>  define i8 @sel_constants_or_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_or_constant:
>>  ; ISEL:       # BB#0:
>> -; ISEL-NEXT:    lis 4, 16383
>> +; ISEL-NEXT:    li 4, 0
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    ori 3, 4, 65535
>> +; ISEL-NEXT:    oris 3, 4, 65535
>>  ; ISEL-NEXT:    li 4, 23
>> -; ISEL-NEXT:    sldi 3, 3, 2
>> +; ISEL-NEXT:    ori 3, 3, 65533
>>  ; ISEL-NEXT:    isel 3, 3, 4, 1
>> -; ISEL-NEXT:    ori 3, 3, 5
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_or_constant:
>>  ; NO_ISEL:       # BB#0:
>> -; NO_ISEL-NEXT:    lis 4, 16383
>> +; NO_ISEL-NEXT:    li 4, 0
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    ori 3, 4, 65535
>> +; NO_ISEL-NEXT:    oris 3, 4, 65535
>>  ; NO_ISEL-NEXT:    li 4, 23
>> -; NO_ISEL-NEXT:    sldi 3, 3, 2
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB29_2
>> +; NO_ISEL-NEXT:    ori 3, 3, 65533
>> +; NO_ISEL-NEXT:    bclr 12, 1, 0
>>  ; NO_ISEL-NEXT:  # BB#1:
>>  ; NO_ISEL-NEXT:    ori 3, 4, 0
>> -; NO_ISEL-NEXT:    b .LBB29_2
>> -; NO_ISEL-NEXT:  .LBB29_2:
>> -; NO_ISEL-NEXT:    ori 3, 3, 5
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = or i8 %sel, 5
>> @@ -741,28 +660,24 @@ define i8 @sel_constants_or_constant(i1
>>  define i8 @sel_constants_xor_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_xor_constant:
>>  ; ISEL:       # BB#0:
>> -; ISEL-NEXT:    lis 4, 16383
>> +; ISEL-NEXT:    li 4, 0
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    ori 3, 4, 65535
>> -; ISEL-NEXT:    li 4, 23
>> -; ISEL-NEXT:    sldi 3, 3, 2
>> +; ISEL-NEXT:    oris 3, 4, 65535
>> +; ISEL-NEXT:    li 4, 18
>> +; ISEL-NEXT:    ori 3, 3, 65529
>>  ; ISEL-NEXT:    isel 3, 3, 4, 1
>> -; ISEL-NEXT:    xori 3, 3, 5
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_xor_constant:
>>  ; NO_ISEL:       # BB#0:
>> -; NO_ISEL-NEXT:    lis 4, 16383
>> +; NO_ISEL-NEXT:    li 4, 0
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    ori 3, 4, 65535
>> -; NO_ISEL-NEXT:    li 4, 23
>> -; NO_ISEL-NEXT:    sldi 3, 3, 2
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB30_2
>> +; NO_ISEL-NEXT:    oris 3, 4, 65535
>> +; NO_ISEL-NEXT:    li 4, 18
>> +; NO_ISEL-NEXT:    ori 3, 3, 65529
>> +; NO_ISEL-NEXT:    bclr 12, 1, 0
>>  ; NO_ISEL-NEXT:  # BB#1:
>>  ; NO_ISEL-NEXT:    ori 3, 4, 0
>> -; NO_ISEL-NEXT:    b .LBB30_2
>> -; NO_ISEL-NEXT:  .LBB30_2:
>> -; NO_ISEL-NEXT:    xori 3, 3, 5
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = xor i8 %sel, 5
>> @@ -772,24 +687,29 @@ define i8 @sel_constants_xor_constant(i1
>>  define i8 @sel_constants_shl_constant(i1 %cond) {
>>  ; ISEL-LABEL: sel_constants_shl_constant:
>>  ; ISEL:       # BB#0:
>> +; ISEL-NEXT:    lis 5, 511
>> +; ISEL-NEXT:    lis 4, 2047
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> +; ISEL-NEXT:    ori 3, 4, 65535
>> +; ISEL-NEXT:    ori 12, 5, 65535
>> +; ISEL-NEXT:    sldi 3, 3, 5
>> +; ISEL-NEXT:    sldi 4, 12, 7
>>  ; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    slwi 3, 3, 5
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_shl_constant:
>>  ; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    lis 5, 511
>> +; NO_ISEL-NEXT:    lis 4, 2047
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> +; NO_ISEL-NEXT:    ori 3, 4, 65535
>> +; NO_ISEL-NEXT:    ori 12, 5, 65535
>> +; NO_ISEL-NEXT:    sldi 3, 3, 5
>> +; NO_ISEL-NEXT:    sldi 4, 12, 7
>>  ; NO_ISEL-NEXT:    bc 12, 1, .LBB31_1
>> -; NO_ISEL-NEXT:    b .LBB31_2
>> +; NO_ISEL-NEXT:    blr
>>  ; NO_ISEL-NEXT:  .LBB31_1:
>>  ; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB31_2:
>> -; NO_ISEL-NEXT:    slwi 3, 3, 5
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = shl i8 %sel, 5
>> @@ -800,23 +720,20 @@ define i8 @sel_constants_lshr_constant(i
>>  ; ISEL-LABEL: sel_constants_lshr_constant:
>>  ; ISEL:       # BB#0:
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> +; ISEL-NEXT:    li 4, 7
>> +; ISEL-NEXT:    li 3, 0
>>  ; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    rlwinm 3, 3, 27, 29, 31
>>  ; ISEL-NEXT:    blr
>>  ;
>>  ; NO_ISEL-LABEL: sel_constants_lshr_constant:
>>  ; NO_ISEL:       # BB#0:
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> +; NO_ISEL-NEXT:    li 4, 7
>> +; NO_ISEL-NEXT:    li 3, 0
>>  ; NO_ISEL-NEXT:    bc 12, 1, .LBB32_1
>> -; NO_ISEL-NEXT:    b .LBB32_2
>> +; NO_ISEL-NEXT:    blr
>>  ; NO_ISEL-NEXT:  .LBB32_1:
>>  ; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB32_2:
>> -; NO_ISEL-NEXT:    rlwinm 3, 3, 27, 29, 31
>>  ; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, i8 -4, i8 23
>>    %bo = lshr i8 %sel, 5
>> @@ -824,127 +741,135 @@ define i8 @sel_constants_lshr_constant(i
>>  }
>>
>>  define i8 @sel_constants_ashr_constant(i1 %cond) {
>> -; ISEL-LABEL: sel_constants_ashr_constant:
>> +; ALL-LABEL: sel_constants_ashr_constant:
>> +; ALL:       # BB#0:
>> +; ALL-NEXT:    clrldi 3, 3, 63
>> +; ALL-NEXT:    neg 3, 3
>> +; ALL-NEXT:    blr
>> +  %sel = select i1 %cond, i8 -4, i8 23
>> +  %bo = ashr i8 %sel, 5
>> +  ret i8 %bo
>> +}
>> +
>> +define double @sel_constants_fadd_constant(i1 %cond) {
>> +; ISEL-LABEL: sel_constants_fadd_constant:
>>  ; ISEL:       # BB#0:
>>  ; ISEL-NEXT:    andi. 3, 3, 1
>> -; ISEL-NEXT:    li 4, -4
>> -; ISEL-NEXT:    li 3, 23
>> -; ISEL-NEXT:    isel 3, 4, 3, 1
>> -; ISEL-NEXT:    srawi 3, 3, 5
>> +; ISEL-NEXT:    addis 4, 2, .LCPI34_0 at toc@ha
>> +; ISEL-NEXT:    addis 3, 2, .LCPI34_1 at toc@ha
>> +; ISEL-NEXT:    addi 4, 4, .LCPI34_0 at toc@l
>> +; ISEL-NEXT:    addi 3, 3, .LCPI34_1 at toc@l
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>> +; ISEL-NEXT:    lxsdx 1, 0, 3
>>  ; ISEL-NEXT:    blr
>>  ;
>> -; NO_ISEL-LABEL: sel_constants_ashr_constant:
>> +; NO_ISEL-LABEL: sel_constants_fadd_constant:
>>  ; NO_ISEL:       # BB#0:
>>  ; NO_ISEL-NEXT:    andi. 3, 3, 1
>> -; NO_ISEL-NEXT:    li 4, -4
>> -; NO_ISEL-NEXT:    li 3, 23
>> -; NO_ISEL-NEXT:    bc 12, 1, .LBB33_1
>> -; NO_ISEL-NEXT:    b .LBB33_2
>> -; NO_ISEL-NEXT:  .LBB33_1:
>> -; NO_ISEL-NEXT:    addi 3, 4, 0
>> -; NO_ISEL-NEXT:  .LBB33_2:
>> -; NO_ISEL-NEXT:    srawi 3, 3, 5
>> +; NO_ISEL-NEXT:    addis 4, 2, .LCPI34_0 at toc@ha
>> +; NO_ISEL-NEXT:    addis 3, 2, .LCPI34_1 at toc@ha
>> +; NO_ISEL-NEXT:    addi 4, 4, .LCPI34_0 at toc@l
>> +; NO_ISEL-NEXT:    addi 3, 3, .LCPI34_1 at toc@l
>> +; NO_ISEL-NEXT:    bc 12, 1, .LBB34_2
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>> +; NO_ISEL-NEXT:    b .LBB34_2
>> +; NO_ISEL-NEXT:  .LBB34_2:
>> +; NO_ISEL-NEXT:    lxsdx 1, 0, 3
>>  ; NO_ISEL-NEXT:    blr
>> -  %sel = select i1 %cond, i8 -4, i8 23
>> -  %bo = ashr i8 %sel, 5
>> -  ret i8 %bo
>> -}
>> -
>> -define double @sel_constants_fadd_constant(i1 %cond) {
>> -; ALL-LABEL: sel_constants_fadd_constant:
>> -; ALL:       # BB#0:
>> -; ALL-NEXT:    andi. 3, 3, 1
>> -; ALL-NEXT:    bc 12, 1, .LBB34_2
>> -; ALL-NEXT:  # BB#1:
>> -; ALL-NEXT:    addis 3, 2, .LCPI34_0 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI34_0 at toc@l
>> -; ALL-NEXT:    lxsdx 0, 0, 3
>> -; ALL-NEXT:    b .LBB34_3
>> -; ALL-NEXT:  .LBB34_2:
>> -; ALL-NEXT:    addis 3, 2, .LCPI34_1 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI34_1 at toc@l
>> -; ALL-NEXT:    lxsspx 0, 0, 3
>> -; ALL-NEXT:  .LBB34_3:
>> -; ALL-NEXT:    addis 3, 2, .LCPI34_2 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI34_2 at toc@l
>> -; ALL-NEXT:    lxsdx 1, 0, 3
>> -; ALL-NEXT:    xsadddp 1, 0, 1
>> -; ALL-NEXT:    blr
>>    %sel = select i1 %cond, double -4.0, double 23.3
>>    %bo = fadd double %sel, 5.1
>>    ret double %bo
>>  }
>>
>>  define double @sel_constants_fsub_constant(i1 %cond) {
>> -; ALL-LABEL: sel_constants_fsub_constant:
>> -; ALL:       # BB#0:
>> -; ALL-NEXT:    andi. 3, 3, 1
>> -; ALL-NEXT:    bc 12, 1, .LBB35_2
>> -; ALL-NEXT:  # BB#1:
>> -; ALL-NEXT:    addis 3, 2, .LCPI35_0 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI35_0 at toc@l
>> -; ALL-NEXT:    lxsdx 0, 0, 3
>> -; ALL-NEXT:    b .LBB35_3
>> -; ALL-NEXT:  .LBB35_2:
>> -; ALL-NEXT:    addis 3, 2, .LCPI35_1 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI35_1 at toc@l
>> -; ALL-NEXT:    lxsspx 0, 0, 3
>> -; ALL-NEXT:  .LBB35_3:
>> -; ALL-NEXT:    addis 3, 2, .LCPI35_2 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI35_2 at toc@l
>> -; ALL-NEXT:    lxsdx 1, 0, 3
>> -; ALL-NEXT:    xsadddp 1, 0, 1
>> -; ALL-NEXT:    blr
>> +; ISEL-LABEL: sel_constants_fsub_constant:
>> +; ISEL:       # BB#0:
>> +; ISEL-NEXT:    andi. 3, 3, 1
>> +; ISEL-NEXT:    addis 4, 2, .LCPI35_0 at toc@ha
>> +; ISEL-NEXT:    addis 3, 2, .LCPI35_1 at toc@ha
>> +; ISEL-NEXT:    addi 4, 4, .LCPI35_0 at toc@l
>> +; ISEL-NEXT:    addi 3, 3, .LCPI35_1 at toc@l
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>> +; ISEL-NEXT:    lxsdx 1, 0, 3
>> +; ISEL-NEXT:    blr
>> +;
>> +; NO_ISEL-LABEL: sel_constants_fsub_constant:
>> +; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    andi. 3, 3, 1
>> +; NO_ISEL-NEXT:    addis 4, 2, .LCPI35_0 at toc@ha
>> +; NO_ISEL-NEXT:    addis 3, 2, .LCPI35_1 at toc@ha
>> +; NO_ISEL-NEXT:    addi 4, 4, .LCPI35_0 at toc@l
>> +; NO_ISEL-NEXT:    addi 3, 3, .LCPI35_1 at toc@l
>> +; NO_ISEL-NEXT:    bc 12, 1, .LBB35_2
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>> +; NO_ISEL-NEXT:    b .LBB35_2
>> +; NO_ISEL-NEXT:  .LBB35_2:
>> +; NO_ISEL-NEXT:    lxsdx 1, 0, 3
>> +; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, double -4.0, double 23.3
>>    %bo = fsub double %sel, 5.1
>>    ret double %bo
>>  }
>>
>>  define double @sel_constants_fmul_constant(i1 %cond) {
>> -; ALL-LABEL: sel_constants_fmul_constant:
>> -; ALL:       # BB#0:
>> -; ALL-NEXT:    andi. 3, 3, 1
>> -; ALL-NEXT:    bc 12, 1, .LBB36_2
>> -; ALL-NEXT:  # BB#1:
>> -; ALL-NEXT:    addis 3, 2, .LCPI36_0 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI36_0 at toc@l
>> -; ALL-NEXT:    lxsdx 0, 0, 3
>> -; ALL-NEXT:    b .LBB36_3
>> -; ALL-NEXT:  .LBB36_2:
>> -; ALL-NEXT:    addis 3, 2, .LCPI36_1 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI36_1 at toc@l
>> -; ALL-NEXT:    lxsspx 0, 0, 3
>> -; ALL-NEXT:  .LBB36_3:
>> -; ALL-NEXT:    addis 3, 2, .LCPI36_2 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI36_2 at toc@l
>> -; ALL-NEXT:    lxsdx 1, 0, 3
>> -; ALL-NEXT:    xsmuldp 1, 0, 1
>> -; ALL-NEXT:    blr
>> +; ISEL-LABEL: sel_constants_fmul_constant:
>> +; ISEL:       # BB#0:
>> +; ISEL-NEXT:    andi. 3, 3, 1
>> +; ISEL-NEXT:    addis 4, 2, .LCPI36_0 at toc@ha
>> +; ISEL-NEXT:    addis 3, 2, .LCPI36_1 at toc@ha
>> +; ISEL-NEXT:    addi 4, 4, .LCPI36_0 at toc@l
>> +; ISEL-NEXT:    addi 3, 3, .LCPI36_1 at toc@l
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>> +; ISEL-NEXT:    lxsdx 1, 0, 3
>> +; ISEL-NEXT:    blr
>> +;
>> +; NO_ISEL-LABEL: sel_constants_fmul_constant:
>> +; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    andi. 3, 3, 1
>> +; NO_ISEL-NEXT:    addis 4, 2, .LCPI36_0 at toc@ha
>> +; NO_ISEL-NEXT:    addis 3, 2, .LCPI36_1 at toc@ha
>> +; NO_ISEL-NEXT:    addi 4, 4, .LCPI36_0 at toc@l
>> +; NO_ISEL-NEXT:    addi 3, 3, .LCPI36_1 at toc@l
>> +; NO_ISEL-NEXT:    bc 12, 1, .LBB36_2
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>> +; NO_ISEL-NEXT:    b .LBB36_2
>> +; NO_ISEL-NEXT:  .LBB36_2:
>> +; NO_ISEL-NEXT:    lxsdx 1, 0, 3
>> +; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, double -4.0, double 23.3
>>    %bo = fmul double %sel, 5.1
>>    ret double %bo
>>  }
>>
>>  define double @sel_constants_fdiv_constant(i1 %cond) {
>> -; ALL-LABEL: sel_constants_fdiv_constant:
>> -; ALL:       # BB#0:
>> -; ALL-NEXT:    andi. 3, 3, 1
>> -; ALL-NEXT:    bc 12, 1, .LBB37_2
>> -; ALL-NEXT:  # BB#1:
>> -; ALL-NEXT:    addis 3, 2, .LCPI37_0 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI37_0 at toc@l
>> -; ALL-NEXT:    lxsdx 0, 0, 3
>> -; ALL-NEXT:    b .LBB37_3
>> -; ALL-NEXT:  .LBB37_2:
>> -; ALL-NEXT:    addis 3, 2, .LCPI37_1 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI37_1 at toc@l
>> -; ALL-NEXT:    lxsspx 0, 0, 3
>> -; ALL-NEXT:  .LBB37_3:
>> -; ALL-NEXT:    addis 3, 2, .LCPI37_2 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI37_2 at toc@l
>> -; ALL-NEXT:    lxsdx 1, 0, 3
>> -; ALL-NEXT:    xsdivdp 1, 0, 1
>> -; ALL-NEXT:    blr
>> +; ISEL-LABEL: sel_constants_fdiv_constant:
>> +; ISEL:       # BB#0:
>> +; ISEL-NEXT:    andi. 3, 3, 1
>> +; ISEL-NEXT:    addis 4, 2, .LCPI37_0 at toc@ha
>> +; ISEL-NEXT:    addis 3, 2, .LCPI37_1 at toc@ha
>> +; ISEL-NEXT:    addi 4, 4, .LCPI37_0 at toc@l
>> +; ISEL-NEXT:    addi 3, 3, .LCPI37_1 at toc@l
>> +; ISEL-NEXT:    isel 3, 3, 4, 1
>> +; ISEL-NEXT:    lxsdx 1, 0, 3
>> +; ISEL-NEXT:    blr
>> +;
>> +; NO_ISEL-LABEL: sel_constants_fdiv_constant:
>> +; NO_ISEL:       # BB#0:
>> +; NO_ISEL-NEXT:    andi. 3, 3, 1
>> +; NO_ISEL-NEXT:    addis 4, 2, .LCPI37_0 at toc@ha
>> +; NO_ISEL-NEXT:    addis 3, 2, .LCPI37_1 at toc@ha
>> +; NO_ISEL-NEXT:    addi 4, 4, .LCPI37_0 at toc@l
>> +; NO_ISEL-NEXT:    addi 3, 3, .LCPI37_1 at toc@l
>> +; NO_ISEL-NEXT:    bc 12, 1, .LBB37_2
>> +; NO_ISEL-NEXT:  # BB#1:
>> +; NO_ISEL-NEXT:    ori 3, 4, 0
>> +; NO_ISEL-NEXT:    b .LBB37_2
>> +; NO_ISEL-NEXT:  .LBB37_2:
>> +; NO_ISEL-NEXT:    lxsdx 1, 0, 3
>> +; NO_ISEL-NEXT:    blr
>>    %sel = select i1 %cond, double -4.0, double 23.3
>>    %bo = fdiv double %sel, 5.1
>>    ret double %bo
>> @@ -959,27 +884,11 @@ define double @sel_constants_frem_consta
>>  ; ALL-NEXT:    addis 3, 2, .LCPI38_0 at toc@ha
>>  ; ALL-NEXT:    addi 3, 3, .LCPI38_0 at toc@l
>>  ; ALL-NEXT:    lxsdx 1, 0, 3
>> -; ALL-NEXT:    b .LBB38_3
>> +; ALL-NEXT:    blr
>>  ; ALL-NEXT:  .LBB38_2:
>>  ; ALL-NEXT:    addis 3, 2, .LCPI38_1 at toc@ha
>>  ; ALL-NEXT:    addi 3, 3, .LCPI38_1 at toc@l
>>  ; ALL-NEXT:    lxsspx 1, 0, 3
>> -; ALL-NEXT:  .LBB38_3:
>> -; ALL-NEXT:    mflr 0
>> -; ALL-NEXT:    std 0, 16(1)
>> -; ALL-NEXT:    stdu 1, -96(1)
>> -; ALL-NEXT:  .Lcfi0:
>> -; ALL-NEXT:    .cfi_def_cfa_offset 96
>> -; ALL-NEXT:  .Lcfi1:
>> -; ALL-NEXT:    .cfi_offset lr, 16
>> -; ALL-NEXT:    addis 3, 2, .LCPI38_2 at toc@ha
>> -; ALL-NEXT:    addi 3, 3, .LCPI38_2 at toc@l
>> -; ALL-NEXT:    lxsdx 2, 0, 3
>> -; ALL-NEXT:    bl fmod
>> -; ALL-NEXT:    nop
>> -; ALL-NEXT:    addi 1, 1, 96
>> -; ALL-NEXT:    ld 0, 16(1)
>> -; ALL-NEXT:    mtlr 0
>>  ; ALL-NEXT:    blr
>>    %sel = select i1 %cond, double -4.0, double 23.3
>>    %bo = frem double %sel, 5.1
>>
>> Modified: llvm/trunk/test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/
>> X86/2010-08-04-MaskedSignedCompare.ll?rev=296699&r1=296698&
>> r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll
>> (original)
>> +++ llvm/trunk/test/CodeGen/X86/2010-08-04-MaskedSignedCompare.ll Wed
>> Mar  1 16:51:31 2017
>> @@ -9,19 +9,21 @@
>>  define i32 @main() nounwind {
>>  ; CHECK-LABEL: main:
>>  ; CHECK:       # BB#0: # %entry
>> +; CHECK-NEXT:    cmpq $0, {{.*}}(%rip)
>> +; CHECK-NEXT:    movb $-106, %al
>> +; CHECK-NEXT:    jne .LBB0_2
>> +; CHECK-NEXT:  # BB#1: # %entry
>>  ; CHECK-NEXT:    xorl %eax, %eax
>> -; CHECK-NEXT:    cmpq {{.*}}(%rip), %rax
>> -; CHECK-NEXT:    sbbl %eax, %eax
>> -; CHECK-NEXT:    andl $150, %eax
>> +; CHECK-NEXT:  .LBB0_2: # %entry
>>  ; CHECK-NEXT:    testb %al, %al
>> -; CHECK-NEXT:    jle .LBB0_1
>> -; CHECK-NEXT:  # BB#2: # %if.then
>> +; CHECK-NEXT:    jle .LBB0_3
>> +; CHECK-NEXT:  # BB#4: # %if.then
>>  ; CHECK-NEXT:    movl $1, {{.*}}(%rip)
>>  ; CHECK-NEXT:    movl $1, %esi
>> -; CHECK-NEXT:    jmp .LBB0_3
>> -; CHECK-NEXT:  .LBB0_1: # %entry.if.end_crit_edge
>> +; CHECK-NEXT:    jmp .LBB0_5
>> +; CHECK-NEXT:  .LBB0_3: # %entry.if.end_crit_edge
>>  ; CHECK-NEXT:    movl {{.*}}(%rip), %esi
>> -; CHECK-NEXT:  .LBB0_3: # %if.end
>> +; CHECK-NEXT:  .LBB0_5: # %if.end
>>  ; CHECK-NEXT:    pushq %rax
>>  ; CHECK-NEXT:    movl $.L.str, %edi
>>  ; CHECK-NEXT:    xorl %eax, %eax
>>
>> Modified: llvm/trunk/test/CodeGen/X86/avx512-insert-extract.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/
>> X86/avx512-insert-extract.ll?rev=296699&r1=296698&r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/CodeGen/X86/avx512-insert-extract.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/avx512-insert-extract.ll Wed Mar  1
>> 16:51:31 2017
>> @@ -1439,11 +1439,8 @@ define zeroext i8 @extractelement_v2i1_a
>>  ; SKX-NEXT:    kmovw %k0, %eax
>>  ; SKX-NEXT:    andl $1, %eax
>>  ; SKX-NEXT:    testb %al, %al
>> -; SKX-NEXT:    je LBB51_2
>> -; SKX-NEXT:  ## BB#1:
>> -; SKX-NEXT:    movb $-1, %al
>> -; SKX-NEXT:  LBB51_2:
>> -; SKX-NEXT:    addb $4, %al
>> +; SKX-NEXT:    sete %al
>> +; SKX-NEXT:    addb $3, %al
>>  ; SKX-NEXT:    movzbl %al, %eax
>>  ; SKX-NEXT:    retq
>>    %t1 = icmp ugt <2 x i64> %a, %b
>> @@ -1555,11 +1552,8 @@ define zeroext i8 @extractelement_v64i1_
>>  ; SKX-NEXT:    kmovw %k0, %eax
>>  ; SKX-NEXT:    andl $1, %eax
>>  ; SKX-NEXT:    testb %al, %al
>> -; SKX-NEXT:    je LBB55_2
>> -; SKX-NEXT:  ## BB#1:
>> -; SKX-NEXT:    movb $-1, %al
>> -; SKX-NEXT:  LBB55_2:
>> -; SKX-NEXT:    addb $4, %al
>> +; SKX-NEXT:    sete %al
>> +; SKX-NEXT:    addb $3, %al
>>  ; SKX-NEXT:    movzbl %al, %eax
>>  ; SKX-NEXT:    retq
>>    %t1 = icmp ugt <64 x i8> %a, %b
>>
>> Modified: llvm/trunk/test/CodeGen/X86/select_const.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/
>> X86/select_const.ll?rev=296699&r1=296698&r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/CodeGen/X86/select_const.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/select_const.ll Wed Mar  1 16:51:31 2017
>> @@ -266,12 +266,10 @@ define <4 x i32> @sel_constants_add_cons
>>  ; CHECK-NEXT:    testb $1, %dil
>>  ; CHECK-NEXT:    jne .LBB22_1
>>  ; CHECK-NEXT:  # BB#2:
>> -; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [11,11,11,11]
>> -; CHECK-NEXT:    paddd {{.*}}(%rip), %xmm0
>> +; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [12,13,14,15]
>>  ; CHECK-NEXT:    retq
>>  ; CHECK-NEXT:  .LBB22_1:
>> -; CHECK-NEXT:    movdqa {{.*#+}} xmm0 = [4294967292,12,1,0]
>> -; CHECK-NEXT:    paddd {{.*}}(%rip), %xmm0
>> +; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [4294967293,14,4,4]
>>  ; CHECK-NEXT:    retq
>>    %sel = select i1 %cond, <4 x i32> <i32 -4, i32 12, i32 1, i32 0>, <4 x
>> i32> <i32 11, i32 11, i32 11, i32 11>
>>    %bo = add <4 x i32> %sel, <i32 1, i32 2, i32 3, i32 4>
>> @@ -284,12 +282,10 @@ define <2 x double> @sel_constants_fmul_
>>  ; CHECK-NEXT:    testb $1, %dil
>>  ; CHECK-NEXT:    jne .LBB23_1
>>  ; CHECK-NEXT:  # BB#2:
>> -; CHECK-NEXT:    movapd {{.*#+}} xmm0 = [2.330000e+01,1.100000e+01]
>> -; CHECK-NEXT:    mulpd {{.*}}(%rip), %xmm0
>> +; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [1.188300e+02,3.454000e+01]
>>  ; CHECK-NEXT:    retq
>>  ; CHECK-NEXT:  .LBB23_1:
>> -; CHECK-NEXT:    movapd {{.*#+}} xmm0 = [-4.000000e+00,1.200000e+01]
>> -; CHECK-NEXT:    mulpd {{.*}}(%rip), %xmm0
>> +; CHECK-NEXT:    movaps {{.*#+}} xmm0 = [-2.040000e+01,3.768000e+01]
>>  ; CHECK-NEXT:    retq
>>    %sel = select i1 %cond, <2 x double> <double -4.0, double 12.0>, <2 x
>> double> <double 23.3, double 11.0>
>>    %bo = fmul <2 x double> %sel, <double 5.1, double 3.14>
>>
>> Modified: llvm/trunk/test/CodeGen/X86/setcc.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/
>> X86/setcc.ll?rev=296699&r1=296698&r2=296699&view=diff
>> ============================================================
>> ==================
>> --- llvm/trunk/test/CodeGen/X86/setcc.ll (original)
>> +++ llvm/trunk/test/CodeGen/X86/setcc.ll Wed Mar  1 16:51:31 2017
>> @@ -49,9 +49,9 @@ define i32 @t4(i32 %a) {
>>  ; CHECK:       ## BB#0:
>>  ; CHECK-NEXT:    movq _v4@{{.*}}(%rip), %rax
>>  ; CHECK-NEXT:    cmpl $1, (%rax)
>> -; CHECK-NEXT:    sbbl %eax, %eax
>> -; CHECK-NEXT:    andl $32768, %eax ## imm = 0x8000
>> -; CHECK-NEXT:    leal 65536(%rax,%rax), %eax
>> +; CHECK-NEXT:    movw $1, %ax
>> +; CHECK-NEXT:    adcw $0, %ax
>> +; CHECK-NEXT:    shll $16, %eax
>>  ; CHECK-NEXT:    retq
>>    %t0 = load i32, i32* @v4, align 4
>>    %not.tobool = icmp eq i32 %t0, 0
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>> IMPORTANT NOTICE: The contents of this email and any attachments are
>> confidential and may also be privileged. If you are not the intended
>> recipient, please notify the sender immediately and do not disclose the
>> contents to any other person, use it for any purpose, or store or copy the
>> information in any medium. Thank you.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170302/c26e85c4/attachment.html>


More information about the llvm-commits mailing list