<div dir="ltr"><div>Here's a first step (but doesn't fix the problem yet):<br><a href="https://reviews.llvm.org/rL297026" rel="noreferrer" target="_blank">https://reviews.llvm.org/rL297<wbr>026</a><br><br></div>But that led to another question:<br><a href="https://reviews.llvm.org/D30665">https://reviews.llvm.org/D30665</a><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Mar 6, 2017 at 8:01 AM, Sanjay Patel <span dir="ltr"><<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>Thanks, Mikael. At first glance, we're missing this fold that exists in InstSimplify in the DAGCombiner:<br><br>  // X % 0 -> undef, we don't need to preserve faults!<br><br></div><div>That's easy to expose with this test compiled for x86-64:<br><br>define i32 @urem0(i32 %x) {<br>  %rem = urem i32 %x, 0<br>  ret i32 %rem<br>}<br><br></div><div> $ ./llc -o - urem0.ll | grep div<br>    divl    %ecx   <--- that was a big waste of time :)<br><br><br></div>I think there's a 2nd problem for all of visitREM/SDIV/UDIV: we try a bunch of combines before the easy "simplifies". Eg:<br><br>  // undef / X -> 0<br>  if (N0.isUndef())<br>    return DAG.getConstant(0, DL, VT);<br>  // X / undef -> undef<br>  if (N1.isUndef())<br>    return N1;<br><br></div>Those folds should be the first thing that we try when visiting a div node to avoid problems like the one you found for 'rem'.<br><br></div>I'll try to expose this with other tests. <br><div><div><br><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Mon, Mar 6, 2017 at 5:57 AM, Mikael Holmén <span dir="ltr"><<a href="mailto:mikael.holmen@ericsson.com" target="_blank">mikael.holmen@ericsson.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">Hi Sanjay,<br>
<br>
On 03/02/2017 06:46 PM, Sanjay Patel via llvm-commits wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This should be fixed with:<br>
<a href="https://reviews.llvm.org/rL296768" rel="noreferrer" target="_blank">https://reviews.llvm.org/rL296<wbr>768</a> <<a href="https://reviews.llvm.org/rL296768" rel="noreferrer" target="_blank">https://reviews.llvm.org/rL29<wbr>6768</a>><br>
<br>
Please let me know if you find any other problems. Thanks!<br>
</blockquote>
<br>
I also found a case that triggers an assertion even with the fix.<br>
<br>
This comes from llvm-stress + bugpoint so might also be odd:<br>
<br>
llc stress_reduced.ll<br>
<br>
gives<br>
<br>
llc: ../lib/CodeGen/SelectionDAG/DA<wbr>GCombiner.cpp:1722: llvm::SDValue (anonymous namespace)::DAGCombiner::foldB<wbr>inOpIntoSelect(llvm::SDNode *): Assertion `(isConstantOrConstantVector(N<wbr>ewCT) || isConstantFPBuildVectorOrConst<wbr>antFP(NewCT)) && "Failed to constant fold a binop with constant operands"' failed.<br>
#0 0x0000000001b482e4 PrintStackTraceSignalHandler(v<wbr>oid*) (build-all/bin/llc+0x1b482e4)<br>
#1 0x0000000001b48a56 SignalHandler(int) (build-all/bin/llc+0x1b48a56)<br>
#2 0x00007f5310ee5330 __restore_rt (/lib/x86_64-linux-gnu/libpthr<wbr>ead.so.0+0x10330)<br>
#3 0x00007f530fad8c37 gsignal /build/eglibc-oGUzwX/eglibc-2.<wbr>19/signal/../nptl/sysdeps/unix<wbr>/sysv/linux/raise.c:56:0<br>
#4 0x00007f530fadc028 abort /build/eglibc-oGUzwX/eglibc-2.<wbr>19/stdlib/abort.c:91:0<br>
#5 0x00007f530fad1bf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2.<wbr>19/assert/assert.c:92:0<br>
#6 0x00007f530fad1ca2 (/lib/x86_64-linux-gnu/libc.so<wbr>.6+0x2fca2)<br>
#7 0x0000000001910187 (anonymous namespace)::DAGCombiner::foldB<wbr>inOpIntoSelect(llvm::SDNode*) (build-all/bin/llc+0x1910187)<br>
#8 0x00000000018b15e2 (anonymous namespace)::DAGCombiner::visit<wbr>(llvm::SDNode*) (build-all/bin/llc+0x18b15e2)<br>
#9 0x00000000018afeec (anonymous namespace)::DAGCombiner::combi<wbr>ne(llvm::SDNode*) (build-all/bin/llc+0x18afeec)<br>
#10 0x00000000018af63a llvm::SelectionDAG::Combine(ll<wbr>vm::CombineLevel, llvm::AAResults&, llvm::CodeGenOpt::Level) (build-all/bin/llc+0x18af63a)<br>
#11 0x0000000001a07edb llvm::SelectionDAGISel::CodeGe<wbr>nAndEmitDAG() (build-all/bin/llc+0x1a07edb)<br>
#12 0x0000000001a06634 llvm::SelectionDAGISel::Select<wbr>AllBasicBlocks(llvm::Function const&) (build-all/bin/llc+0x1a06634)<br>
#13 0x0000000001a029fa llvm::SelectionDAGISel::runOnM<wbr>achineFunction(llvm::MachineFu<wbr>nction&) (build-all/bin/llc+0x1a029fa)<br>
#14 0x0000000000f7b331 (anonymous namespace)::X86DAGToDAGISel::r<wbr>unOnMachineFunction(llvm::Mach<wbr>ineFunction&) (build-all/bin/llc+0xf7b331)<br>
#15 0x00000000013ab952 llvm::MachineFunctionPass::run<wbr>OnFunction(llvm::Function&) (build-all/bin/llc+0x13ab952)<br>
#16 0x000000000163eeb8 llvm::FPPassManager::runOnFunc<wbr>tion(llvm::Function&) (build-all/bin/llc+0x163eeb8)<br>
#17 0x000000000163f0f8 llvm::FPPassManager::runOnModu<wbr>le(llvm::Module&) (build-all/bin/llc+0x163f0f8)<br>
#18 0x000000000163f5d5 llvm::legacy::PassManagerImpl:<wbr>:run(llvm::Module&) (build-all/bin/llc+0x163f5d5)<br>
#19 0x000000000068bf59 compileModule(char**, llvm::LLVMContext&) (build-all/bin/llc+0x68bf59)<br>
#20 0x0000000000688f4b main (build-all/bin/llc+0x688f4b)<br>
#21 0x00007f530fac3f45 __libc_start_main /build/eglibc-oGUzwX/eglibc-2.<wbr>19/csu/libc-start.c:321:0<br>
#22 0x000000000068716b _start (build-all/bin/llc+0x68716b)<br>
Stack dump:<br>
0.      Program arguments: build-all/bin/llc stress_reduced.ll<br>
1.      Running pass 'Function Pass Manager' on module 'stress_reduced.ll'.<br>
2.      Running pass 'X86 DAG->DAG Instruction Selection' on function '@autogen_SD30383'<br>
Abort<br>
<br>
Regards,<br>
Mikael<br>
<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
<br>
On Thu, Mar 2, 2017 at 9:00 AM, Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a><br>
<mailto:<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a><wbr>>> wrote:<br>
<br>
    Thanks, Dave! Taking a look now. Sorry about the bug.<br>
<br>
    On Thu, Mar 2, 2017 at 8:48 AM, David Green <<a href="mailto:David.Green@arm.com" target="_blank">David.Green@arm.com</a><br>
    <mailto:<a href="mailto:David.Green@arm.com" target="_blank">David.Green@arm.com</a>>> wrote:<br>
<br>
        Hello,<br>
<br>
<br>
        I have an error for you. Compiled with:<br>
<br>
        clang -O3 -target aarch64-linux-gnu -mcpu=cortex-a57 -c reduce.c<br>
<br>
        void d(unsigned a, long* b, long c) {<br>
          long f = __builtin_neon_vcled_s64(a, c);<br>
          long e = __builtin_neon_vshrd_n_u64(f, 20);<br>
          f = 15281557956303287032 + e;<br>
          *b = f;<br>
          if (15281557956303287032 != c)<br>
            g();<br>
        }<br>
<br>
<br>
        It's been fairly heavily creduced, so apologies for it's<br>
        oddness. The original was auto generated, so may not be a lot<br>
        better. Let me know if you need a larger version though.<br>
<br>
<br>
        clang-5.0: ../lib/CodeGen/SelectionDAG/DA<wbr>GCombiner.cpp:1794:<br>
        llvm::SDValue<br>
        {anonymous}::DAGCombiner::fold<wbr>BinOpIntoSelect(llvm::SDNode*)<wbr>:<br>
        Assertion `(isConstantOrConstantVector(N<wbr>ewCT) ||<br>
        isConstantFPBuildVectorOrConst<wbr>antFP(NewCT)) && "Failed to<br>
        constant fold a binop with constant operands"' failed.<br>
        #0 0x00007f96c5604d69<br>
        llvm::sys::PrintStackTrace(llv<wbr>m::raw_ostream&)<br>
        /work/llvm-git/build/../lib/Su<wbr>pport/Unix/Signals.inc:402:0<br>
        #1 0x00007f96c5604dfa PrintStackTraceSignalHandler(v<wbr>oid*)<br>
        /work/llvm-git/build/../lib/Su<wbr>pport/Unix/Signals.inc:466:0<br>
        #2 0x00007f96c5603292 llvm::sys::RunSignalHandlers()<br>
        /work/llvm-git/build/../lib/Su<wbr>pport/Signals.cpp:44:0<br>
        #3 0x00007f96c5604700 SignalHandler(int)<br>
        /work/llvm-git/build/../lib/Su<wbr>pport/Unix/Signals.inc:256:0<br>
        #4 0x00007f96c2d9ecb0 (/lib/x86_64-linux-gnu/libc.so<wbr>.6+0x36cb0)<br>
        #5 0x00007f96c2d9ec37 gsignal<br>
        /build/eglibc-oGUzwX/eglibc-2.<wbr>19/signal/../nptl/sysdeps/unix<wbr>/sysv/linux/raise.c:56:0<br>
        #6 0x00007f96c2da2028 abort<br>
        /build/eglibc-oGUzwX/eglibc-2.<wbr>19/stdlib/abort.c:91:0<br>
        #7 0x00007f96c2d97bf6 __assert_fail_base<br>
        /build/eglibc-oGUzwX/eglibc-2.<wbr>19/assert/assert.c:92:0<br>
        #8 0x00007f96c2d97ca2 (/lib/x86_64-linux-gnu/libc.so<wbr>.6+0x2fca2)<br>
        #9 0x00007f96c24eaacd (anonymous<br>
        namespace)::DAGCombiner::foldB<wbr>inOpIntoSelect(llvm::SDNode*)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/DAGCombiner<wbr>.cpp:1796:0<br>
        #10 0x00007f96c24eb07c (anonymous<br>
        namespace)::DAGCombiner::visit<wbr>ADD(llvm::SDNode*)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/DAGCombiner<wbr>.cpp:1852:0<br>
        #11 0x00007f96c24e7f77 (anonymous<br>
        namespace)::DAGCombiner::visit<wbr>(llvm::SDNode*)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/DAGCombiner<wbr>.cpp:1385:0<br>
        #12 0x00007f96c24e87c3 (anonymous<br>
        namespace)::DAGCombiner::combi<wbr>ne(llvm::SDNode*)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/DAGCombiner<wbr>.cpp:1481:0<br>
        #13 0x00007f96c24e7ba4 (anonymous<br>
        namespace)::DAGCombiner::Run(l<wbr>lvm::CombineLevel)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/DAGCombiner<wbr>.cpp:1335:0<br>
        #14 0x00007f96c254cac8<br>
        llvm::SelectionDAG::Combine(ll<wbr>vm::CombineLevel,<br>
        llvm::AAResults&, llvm::CodeGenOpt::Level)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/DAGCombiner<wbr>.cpp:16196:0<br>
        #15 0x00007f96c27190a5<br>
        llvm::SelectionDAGISel::CodeGe<wbr>nAndEmitDAG()<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/SelectionDA<wbr>GISel.cpp:807:0<br>
        #16 0x00007f96c2718861<br>
        llvm::SelectionDAGISel::Select<wbr>BasicBlock(llvm::ilist_iterato<wbr>r<llvm::ilist_detail::node_opt<wbr>ions<llvm::Instruction,<br>
        true, false, void>, false, true>,<br>
        llvm::ilist_iterator<llvm::ili<wbr>st_detail::node_options<llvm::<wbr>Instruction,<br>
        true, false, void>, false, true>, bool&)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/SelectionDA<wbr>GISel.cpp:728:0<br>
        #17 0x00007f96c271d65d<br>
        llvm::SelectionDAGISel::Select<wbr>AllBasicBlocks(llvm::Function<br>
        const&)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/SelectionDA<wbr>GISel.cpp:1694:0<br>
        #18 0x00007f96c2717679<br>
        llvm::SelectionDAGISel::runOnM<wbr>achineFunction(llvm::MachineFu<wbr>nction&)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/SelectionDAG/SelectionDA<wbr>GISel.cpp:543:0<br>
        #19 0x00007f96cb575b86 (anonymous<br>
        namespace)::AArch64DAGToDAGISe<wbr>l::runOnMachineFunction(llvm::<wbr>MachineFunction&)<br>
        /work/llvm-git/build/../lib/Ta<wbr>rget/AArch64/AArch64ISelDAGToD<wbr>AG.cpp:58:0<br>
        #20 0x00007f96c776a2c1<br>
        llvm::MachineFunctionPass::run<wbr>OnFunction(llvm::Function&)<br>
        /work/llvm-git/build/../lib/Co<wbr>deGen/MachineFunctionPass.cpp:<wbr>62:0<br>
        #21 0x00007f96c6ddac78<br>
        llvm::FPPassManager::runOnFunc<wbr>tion(llvm::Function&)<br>
        /work/llvm-git/build/../lib/IR<wbr>/LegacyPassManager.cpp:1513:0<br>
        #22 0x00007f96c6ddae0b<br>
        llvm::FPPassManager::runOnModu<wbr>le(llvm::Module&)<br>
        /work/llvm-git/build/../lib/IR<wbr>/LegacyPassManager.cpp:1534:0<br>
        #23 0x00007f96c6ddb1a6 (anonymous<br>
        namespace)::MPPassManager::run<wbr>OnModule(llvm::Module&)<br>
        /work/llvm-git/build/../lib/IR<wbr>/LegacyPassManager.cpp:1590:0<br>
        #24 0x00007f96c6ddb8f6<br>
        llvm::legacy::PassManagerImpl:<wbr>:run(llvm::Module&)<br>
        /work/llvm-git/build/../lib/IR<wbr>/LegacyPassManager.cpp:1693:0<br>
        #25 0x00007f96c6ddbb37<br>
        llvm::legacy::PassManager::run<wbr>(llvm::Module&)<br>
        /work/llvm-git/build/../lib/IR<wbr>/LegacyPassManager.cpp:1725:0<br>
        #26 0x00007f96c3e6dec5 (anonymous<br>
        namespace)::EmitAssemblyHelper<wbr>::EmitAssembly(clang::BackendA<wbr>ction,<br>
        std::unique_ptr<llvm::raw_pwri<wbr>te_stream,<br>
        std::default_delete<llvm::raw_<wbr>pwrite_stream> >)<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/CodeGen/BackendUtil.<wbr>cpp:730:0<br>
        #27 0x00007f96c3e6f886<br>
        clang::EmitBackendOutput(clang<wbr>::DiagnosticsEngine&,<br>
        clang::HeaderSearchOptions const&, clang::CodeGenOptions const&,<br>
        clang::TargetOptions const&, clang::LangOptions const&,<br>
        llvm::DataLayout const&, llvm::Module*, clang::BackendAction,<br>
        std::unique_ptr<llvm::raw_pwri<wbr>te_stream,<br>
        std::default_delete<llvm::raw_<wbr>pwrite_stream> >)<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/CodeGen/BackendUtil.<wbr>cpp:999:0<br>
        #28 0x00007f96c418381d<br>
        clang::BackendConsumer::Handle<wbr>TranslationUnit(clang::ASTCont<wbr>ext&) /work/llvm-git/build/../tools/<wbr>clang/lib/CodeGen/CodeGenActio<wbr>n.cpp:243:0<br>
        #29 0x00007f96bf743d7b clang::ParseAST(clang::Sema&, bool, bool)<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/Parse/ParseAST.cpp:1<wbr>61:0<br>
        #30 0x00007f96c382b3a4 clang::ASTFrontendAction::Exec<wbr>uteAction()<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/Frontend/FrontendAct<wbr>ion.cpp:569:0<br>
        #31 0x00007f96c4180899 clang::CodeGenAction::ExecuteA<wbr>ction()<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/CodeGen/CodeGenActio<wbr>n.cpp:973:0<br>
        #32 0x00007f96c382ae49 clang::FrontendAction::Execute<wbr>()<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/Frontend/FrontendAct<wbr>ion.cpp:472:0<br>
        #33 0x00007f96c37bff23<br>
        clang::CompilerInstance::Execu<wbr>teAction(clang::FrontendAction<wbr>&)<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/Frontend/CompilerIns<wbr>tance.cpp:951:0<br>
        #34 0x00007f96c34d5d2a<br>
        clang::ExecuteCompilerInvocati<wbr>on(clang::CompilerInstance*)<br>
        /work/llvm-git/build/../tools/<wbr>clang/lib/FrontendTool/Execute<wbr>CompilerInvocation.cpp:249:0<br>
        #35 0x000000000044a53f cc1_main(llvm::ArrayRef<char const*>,<br>
        char const*, void*)<br>
        /work/llvm-git/build/../tools/<wbr>clang/tools/driver/cc1_main.cp<wbr>p:221:0<br>
        #36 0x000000000044059c ExecuteCC1Tool(llvm::ArrayRef<<wbr>char<br>
        const*>, llvm::StringRef)<br>
        /work/llvm-git/build/../tools/<wbr>clang/tools/driver/driver.cpp:<wbr>299:0<br>
        #37 0x000000000044119a main<br>
        /work/llvm-git/build/../tools/<wbr>clang/tools/driver/driver.cpp:<wbr>380:0<br>
        #38 0x00007f96c2d89f45 __libc_start_main<br>
        /build/eglibc-oGUzwX/eglibc-2.<wbr>19/csu/libc-start.c:321:0<br>
        #39 0x000000000043e009 _start<br>
        (/work/llvm-git/build/bin/clan<wbr>g-5.0+0x43e009)<br>
        Stack dump:<br>
        0.Program arguments: /work/llvm-git/build/bin/clang<wbr>-5.0 -cc1<br>
        -triple aarch64--linux-gnu -emit-obj -disable-free<br>
        -main-file-name reduce.c -mrelocation-model static<br>
        -mthread-model posix -mdisable-fp-elim -fmath-errno<br>
        -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu<br>
        cortex-a57 -target-feature +neon -target-feature +crc<br>
        -target-feature +crypto -target-abi aapcs -dwarf-column-info<br>
        -debugger-tuning=gdb -coverage-notes-file<br>
        /work/tmp/testing/emp/reduce/r<wbr>educe.gcno -resource-dir<br>
        /work/llvm-git/build/lib/clang<wbr>/5.0.0 -internal-isystem<br>
        /usr/local/include -internal-isystem<br>
        /work/llvm-git/build/lib/clang<wbr>/5.0.0/include<br>
        -internal-externc-isystem /include -internal-externc-isystem<br>
        /usr/include -O3 -fdebug-compilation-dir<br>
        /work/tmp/testing/emp/reduce -ferror-limit 19 -fmessage-length<br>
        102 -fallow-half-arguments-and-ret<wbr>urns -fno-signed-char<br>
        -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics<br>
        -vectorize-loops -vectorize-slp -o reduce.o -x c reduce.c<br>
        1.<eof> parser at end of file<br>
        2.Code generation<br>
        3.Running pass 'Function Pass Manager' on module 'reduce.c'.<br>
        4.Running pass 'AArch64 Instruction Selection' on function '@d'<br>
        clang-5.0: error: unable to execute command: Aborted (core dumped)<br>
        clang-5.0: error: clang frontend command failed due to signal<br>
        (use -v to see invocation)<br>
        clang version 5.0.0 (<a href="http://llvm.org/git/clang.git" rel="noreferrer" target="_blank">http://llvm.org/git/clang.git</a><br>
        77b000e5f923dc575e614259c3506e<wbr>d5bc855297)<br>
        (<a href="http://llvm.org/git/llvm.git" rel="noreferrer" target="_blank">http://llvm.org/git/llvm.git</a><br>
        4f2d8229c1c2152df50669701f0fe4<wbr>4f5e412fa3)<br>
        Target: aarch64--linux-gnu<br>
        Thread model: posix<br>
        InstalledDir: /work/llvm-git/build/bin<br>
        clang-5.0: note: diagnostic msg: PLEASE submit a bug report to<br>
        <a href="http://llvm.org/bugs/" rel="noreferrer" target="_blank">http://llvm.org/bugs/</a> and include the crash backtrace,<br>
        preprocessed source, and associated run script.<br>
        clang-5.0: note: diagnostic msg:<br>
        ********************<br>
<br>
        PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:<br>
        Preprocessed source(s) and associated run script(s) are located at:<br>
        clang-5.0: note: diagnostic msg: /tmp/reduce-d3ed6e.c<br>
        clang-5.0: note: diagnostic msg: /tmp/reduce-d3ed6e.sh<br>
        clang-5.0: note: diagnostic msg:<br>
<br>
        ********************<br>
<br>
<br>
<br>
        Cheers<br>
        Dave<br>
<br>
        ------------------------------<wbr>------------------------------<wbr>------------<br>
        *From:* llvm-commits <<a href="mailto:llvm-commits-bounces@lists.llvm.org" target="_blank">llvm-commits-bounces@lists.ll<wbr>vm.org</a><br>
        <mailto:<a href="mailto:llvm-commits-bounces@lists.llvm.org" target="_blank">llvm-commits-bounces@l<wbr>ists.llvm.org</a>>> on behalf of<br>
        Sanjay Patel via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
        <mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llv<wbr>m.org</a>>><br>
        *Sent:* 01 March 2017 22:51<br>
        *To:* <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
        <mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llv<wbr>m.org</a>><br>
        *Subject:* [llvm] r296699 - [DAGCombiner] fold binops with<br>
        constant into select-of-constants<br>
<br>
        Author: spatel<br>
        Date: Wed Mar  1 16:51:31 2017<br>
        New Revision: 296699<br>
<br>
        URL: <a href="http://llvm.org/viewvc/llvm-project?rev=296699&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=296699&view=rev</a><br>
        <<a href="http://llvm.org/viewvc/llvm-project?rev=296699&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject?rev=296699&view=rev</a>><br>
        Log:<br>
        [DAGCombiner] fold binops with constant into select-of-constants<br>
<br>
        This is part of the ongoing attempt to improve select codegen<br>
        for all targets and select<br>
        canonicalization in IR (see D24480 for more background). The<br>
        transform is a subset of what<br>
        is done in InstCombine's FoldOpIntoSelect().<br>
<br>
        I first noticed a regression in the x86 avx512-insert-extract.ll<br>
        tests with a patch that<br>
        hopes to convert more selects to basic math ops. This appears to<br>
        be a general missing DAG<br>
        transform though, so I added tests for all standard binops in<br>
        rL296621<br>
        (PowerPC was chosen semi-randomly; it has scripted FileCheck<br>
        support, but so do ARM and x86).<br>
<br>
        The poor output for "sel_constants_shl_constant" is tracked with:<br>
        <a href="https://bugs.llvm.org/show_bug.cgi?id=32105" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_bug<wbr>.cgi?id=32105</a><br>
        <<a href="https://bugs.llvm.org/show_bug.cgi?id=32105" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_bu<wbr>g.cgi?id=32105</a>><br>
<br>
        Differential Revision: <a href="https://reviews.llvm.org/D30502" rel="noreferrer" target="_blank">https://reviews.llvm.org/D3050<wbr>2</a><br>
        <<a href="https://reviews.llvm.org/D30502" rel="noreferrer" target="_blank">https://reviews.llvm.org/D305<wbr>02</a>><br>
<br>
        Modified:<br>
            llvm/trunk/lib/CodeGen/Selecti<wbr>onDAG/DAGCombiner.cpp<br>
            llvm/trunk/test/CodeGen/ARM/se<wbr>lect_xform.ll<br>
            llvm/trunk/test/CodeGen/PowerP<wbr>C/select_const.ll<br>
            llvm/trunk/test/CodeGen/X86/20<wbr>10-08-04-MaskedSignedCompare.l<wbr>l<br>
            llvm/trunk/test/CodeGen/X86/av<wbr>x512-insert-extract.ll<br>
            llvm/trunk/test/CodeGen/X86/se<wbr>lect_const.ll<br>
            llvm/trunk/test/CodeGen/X86/se<wbr>tcc.ll<br>
<br>
        Modified: llvm/trunk/lib/CodeGen/Selecti<wbr>onDAG/DAGCombiner.cpp<br>
        URL:<br>
        <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=296699&r1=296698&r2=296699&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/CodeGen/S<wbr>electionDAG/DAGCombiner.cpp?re<wbr>v=296699&r1=296698&r2=296699&<wbr>view=diff</a><br>
        <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=296699&r1=296698&r2=296699&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>SelectionDAG/DAGCombiner.cpp?r<wbr>ev=296699&r1=296698&r2=296699&<wbr>view=diff</a>><br>
        ==============================<wbr>==============================<wbr>==================<br>
        --- llvm/trunk/lib/CodeGen/Selecti<wbr>onDAG/DAGCombiner.cpp (original)<br>
        +++ llvm/trunk/lib/CodeGen/Selecti<wbr>onDAG/DAGCombiner.cpp Wed Mar<br>
        1 16:51:31 2017<br>
        @@ -337,6 +337,7 @@ namespace {<br>
             SDValue visitShiftByConstant(SDNode *N, ConstantSDNode *Amt);<br>
<br>
             SDValue foldSelectOfConstants(SDNode *N);<br>
        +    SDValue foldBinOpIntoSelect(SDNode *BO);<br>
             bool SimplifySelectOps(SDNode *SELECT, SDValue LHS, SDValue<br>
        RHS);<br>
             SDValue SimplifyBinOpWithSameOpcodeHan<wbr>ds(SDNode *N);<br>
             SDValue SimplifySelect(const SDLoc &DL, SDValue N0, SDValue<br>
        N1, SDValue N2);<br>
        @@ -1747,6 +1748,59 @@ static ConstantSDNode *getAsNonOpaqueCon<br>
           return Const != nullptr && !Const->isOpaque() ? Const : nullptr;<br>
         }<br>
<br>
        +SDValue DAGCombiner::foldBinOpIntoSele<wbr>ct(SDNode *BO) {<br>
        +  auto BinOpcode = BO->getOpcode();<br>
        +  assert((BinOpcode == ISD::ADD || BinOpcode == ISD::SUB ||<br>
        +          BinOpcode == ISD::MUL || BinOpcode == ISD::SDIV ||<br>
        +          BinOpcode == ISD::UDIV || BinOpcode == ISD::SREM ||<br>
        +          BinOpcode == ISD::UREM || BinOpcode == ISD::AND ||<br>
        +          BinOpcode == ISD::OR || BinOpcode == ISD::XOR ||<br>
        +          BinOpcode == ISD::SHL || BinOpcode == ISD::SRL ||<br>
        +          BinOpcode == ISD::SRA || BinOpcode == ISD::FADD ||<br>
        +          BinOpcode == ISD::FSUB || BinOpcode == ISD::FMUL ||<br>
        +          BinOpcode == ISD::FDIV || BinOpcode == ISD::FREM) &&<br>
        +         "Unexpected binary operator");<br>
        +<br>
        +  SDValue C1 = BO->getOperand(1);<br>
        +  if (!isConstantOrConstantVector(C<wbr>1) &&<br>
        +      !isConstantFPBuildVectorOrCons<wbr>tantFP(C1))<br>
        +    return SDValue();<br>
        +<br>
        +  // Don't do this unless the old select is going away. We want<br>
        to eliminate the<br>
        +  // binary operator, not replace a binop with a select.<br>
        +  // TODO: Handle ISD::SELECT_CC.<br>
        +  SDValue Sel = BO->getOperand(0);<br>
        +  if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse())<br>
        +    return SDValue();<br>
        +<br>
        +  SDValue CT = Sel.getOperand(1);<br>
        +  if (!isConstantOrConstantVector(C<wbr>T) &&<br>
        +      !isConstantFPBuildVectorOrCons<wbr>tantFP(CT))<br>
        +    return SDValue();<br>
        +<br>
        +  SDValue CF = Sel.getOperand(2);<br>
        +  if (!isConstantOrConstantVector(C<wbr>F) &&<br>
        +      !isConstantFPBuildVectorOrCons<wbr>tantFP(CF))<br>
        +    return SDValue();<br>
        +<br>
        +  // We have a select-of-constants followed by a binary<br>
        operator with a<br>
        +  // constant. Eliminate the binop by pulling the constant math<br>
        into the select.<br>
        +  // Example: add (select Cond, CT, CF), C1 --> select Cond, CT<br>
        + C1, CF + C1<br>
        +  EVT VT = Sel.getValueType();<br>
        +  SDLoc DL(Sel);<br>
        +  SDValue NewCT = DAG.getNode(BinOpcode, DL, VT, CT, C1);<br>
        +  assert((isConstantOrConstantVe<wbr>ctor(NewCT) ||<br>
        +          isConstantFPBuildVectorOrConst<wbr>antFP(NewCT)) &&<br>
        +         "Failed to constant fold a binop with constant operands");<br>
        +<br>
        +  SDValue NewCF = DAG.getNode(BinOpcode, DL, VT, CF, C1);<br>
        +  assert((isConstantOrConstantVe<wbr>ctor(NewCF) ||<br>
        +          isConstantFPBuildVectorOrConst<wbr>antFP(NewCF)) &&<br>
        +         "Failed to constant fold a binop with constant operands");<br>
        +<br>
        +  return DAG.getSelect(DL, VT, Sel.getOperand(0), NewCT, NewCF);<br>
        +}<br>
        +<br>
         SDValue DAGCombiner::visitADD(SDNode *N) {<br>
           SDValue N0 = N->getOperand(0);<br>
           SDValue N1 = N->getOperand(1);<br>
        @@ -1795,6 +1849,9 @@ SDValue DAGCombiner::visitADD(SDNode *N)<br>
               }<br>
           }<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // reassociate add<br>
           if (SDValue RADD = ReassociateOps(ISD::ADD, DL, N0, N1))<br>
             return RADD;<br>
        @@ -1999,6 +2056,9 @@ SDValue DAGCombiner::visitSUB(SDNode *N)<br>
                                               N1.getNode());<br>
           }<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           ConstantSDNode *N1C = getAsNonOpaqueConstant(N1);<br>
<br>
           // fold (sub x, c) -> (add x, -c)<br>
        @@ -2210,6 +2270,10 @@ SDValue DAGCombiner::visitMUL(SDNode *N)<br>
           // fold (mul x, 1) -> x<br>
           if (N1IsConst && ConstValue1 == 1 && IsFullSplat)<br>
             return N0;<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // fold (mul x, -1) -> 0-x<br>
           if (N1IsConst && ConstValue1.isAllOnesValue()) {<br>
             SDLoc DL(N);<br>
        @@ -2401,6 +2465,9 @@ SDValue DAGCombiner::visitSDIV(SDNode *N<br>
             return DAG.getNode(ISD::SUB, DL, VT,<br>
                                DAG.getConstant(0, DL, VT), N0);<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // If we know the sign bits of both operands are zero,<br>
        strength reduce to a<br>
           // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2<br>
           if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))<br>
        @@ -2493,6 +2560,9 @@ SDValue DAGCombiner::visitUDIV(SDNode *N<br>
                                                             N0C, N1C))<br>
               return Folded;<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // fold (udiv x, (1 << c)) -> x >>u c<br>
           if (isConstantOrConstantVector(N1<wbr>, /*NoOpaques*/ true) &&<br>
               DAG.isKnownToBeAPowerOfTwo(N1<wbr>)) {<br>
        @@ -2561,6 +2631,9 @@ SDValue DAGCombiner::visitREM(SDNode *N)<br>
             if (SDValue Folded = DAG.FoldConstantArithmetic(Opc<wbr>ode, DL,<br>
        VT, N0C, N1C))<br>
               return Folded;<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           if (isSigned) {<br>
             // If we know the sign bits of both operands are zero,<br>
        strength reduce to a<br>
             // urem instead.  Handles (X & 0x0FFFFFFF) %s 16 -> X&15<br>
        @@ -3267,6 +3340,10 @@ SDValue DAGCombiner::visitAND(SDNode *N)<br>
           if (N1C && DAG.MaskedValueIsZero(SDValue(<wbr>N, 0),<br>
<br>
        APInt::getAllOnesValue(BitWidt<wbr>h)))<br>
             return DAG.getConstant(0, SDLoc(N), VT);<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // reassociate and<br>
           if (SDValue RAND = ReassociateOps(ISD::AND, SDLoc(N), N0, N1))<br>
             return RAND;<br>
        @@ -4008,6 +4085,10 @@ SDValue DAGCombiner::visitOR(SDNode *N)<br>
           // fold (or x, -1) -> -1<br>
           if (isAllOnesConstant(N1))<br>
             return N1;<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // fold (or x, c) -> c iff (x & ~c) == 0<br>
           if (N1C && DAG.MaskedValueIsZero(N0, ~N1C->getAPIntValue()))<br>
             return N1;<br>
        @@ -4753,6 +4834,10 @@ SDValue DAGCombiner::visitXOR(SDNode *N)<br>
           // fold (xor x, 0) -> x<br>
           if (isNullConstant(N1))<br>
             return N0;<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // reassociate xor<br>
           if (SDValue RXOR = ReassociateOps(ISD::XOR, SDLoc(N), N0, N1))<br>
             return RXOR;<br>
        @@ -5040,6 +5125,10 @@ SDValue DAGCombiner::visitSHL(SDNode *N)<br>
           // fold (shl undef, x) -> 0<br>
           if (N0.isUndef())<br>
             return DAG.getConstant(0, SDLoc(N), VT);<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // if (shl x, c) is known to be zero, return 0<br>
           if (DAG.MaskedValueIsZero(SDValue<wbr>(N, 0),<br>
                                     APInt::getAllOnesValue(OpSize<wbr>InBits)))<br>
        @@ -5243,6 +5332,10 @@ SDValue DAGCombiner::visitSRA(SDNode *N)<br>
           // fold (sra x, 0) -> x<br>
           if (N1C && N1C->isNullValue())<br>
             return N0;<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // fold (sra (shl x, c1), c1) -> sext_inreg for some c1 and<br>
        target supports<br>
           // sext_inreg.<br>
           if (N1C && N0.getOpcode() == ISD::SHL && N1 ==<br>
        N0.getOperand(1)) {<br>
        @@ -5390,6 +5483,10 @@ SDValue DAGCombiner::visitSRL(SDNode *N)<br>
           // fold (srl x, 0) -> x<br>
           if (N1C && N1C->isNullValue())<br>
             return N0;<br>
        +<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // if (srl x, c) is known to be zero, return 0<br>
           if (N1C && DAG.MaskedValueIsZero(SDValue(<wbr>N, 0),<br>
<br>
        APInt::getAllOnesValue(OpSizeI<wbr>nBits)))<br>
        @@ -9064,6 +9161,9 @@ SDValue DAGCombiner::visitFADD(SDNode *N<br>
           if (N0CFP && !N1CFP)<br>
             return DAG.getNode(ISD::FADD, DL, VT, N1, N0, Flags);<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // fold (fadd A, (fneg B)) -> (fsub A, B)<br>
           if ((!LegalOperations ||<br>
        TLI.isOperationLegalOrCustom(I<wbr>SD::FSUB, VT)) &&<br>
               isNegatibleForFree(N1, LegalOperations, TLI, &Options) == 2)<br>
        @@ -9211,6 +9311,9 @@ SDValue DAGCombiner::visitFSUB(SDNode *N<br>
           if (N0CFP && N1CFP)<br>
             return DAG.getNode(ISD::FSUB, DL, VT, N0, N1, Flags);<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           // fold (fsub A, (fneg B)) -> (fadd A, B)<br>
           if (isNegatibleForFree(N1, LegalOperations, TLI, &Options))<br>
             return DAG.getNode(ISD::FADD, DL, VT, N0,<br>
        @@ -9290,6 +9393,9 @@ SDValue DAGCombiner::visitFMUL(SDNode *N<br>
           if (N1CFP && N1CFP->isExactlyValue(1.0))<br>
             return N0;<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           if (Options.UnsafeFPMath) {<br>
             // fold (fmul A, 0) -> 0<br>
             if (N1CFP && N1CFP->isZero())<br>
        @@ -9544,6 +9650,9 @@ SDValue DAGCombiner::visitFDIV(SDNode *N<br>
           if (N0CFP && N1CFP)<br>
             return DAG.getNode(ISD::FDIV, SDLoc(N), VT, N0, N1, Flags);<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           if (Options.UnsafeFPMath) {<br>
             // fold (fdiv X, c2) -> fmul X, 1/c2 if losing precision is<br>
        acceptable.<br>
             if (N1CFP) {<br>
        @@ -9647,6 +9756,9 @@ SDValue DAGCombiner::visitFREM(SDNode *N<br>
             return DAG.getNode(ISD::FREM, SDLoc(N), VT, N0, N1,<br>
                                &cast<BinaryWithFlagsSDNode>(N<wbr>)->Flags);<br>
<br>
        +  if (SDValue NewSel = foldBinOpIntoSelect(N))<br>
        +    return NewSel;<br>
        +<br>
           return SDValue();<br>
         }<br>
<br>
<br>
        Modified: llvm/trunk/test/CodeGen/ARM/se<wbr>lect_xform.ll<br>
        URL:<br>
        <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/select_xform.ll?rev=296699&r1=296698&r2=296699&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>ARM/select_xform.ll?rev=296699<wbr>&r1=296698&r2=296699&view=diff</a><br>
        <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/select_xform.ll?rev=296699&r1=296698&r2=296699&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/test/CodeGen<wbr>/ARM/select_xform.ll?rev=29669<wbr>9&r1=296698&r2=296699&view=<wbr>diff</a>><br>
        ==============================<wbr>==============================<wbr>==================<br>
        --- llvm/trunk/test/CodeGen/ARM/se<wbr>lect_xform.ll (original)<br>
        +++ llvm/trunk/test/CodeGen/ARM/se<wbr>lect_xform.ll Wed Mar  1<br>
        16:51:31 2017<br>
        @@ -223,21 +223,19 @@ entry:<br>
           ret i32 %add<br>
         }<br>
<br>
        -; Do not fold the xor into the select<br>
        +; Fold the xor into the select.<br>
         define i32 @t15(i32 %p) {<br>
         entry:<br>
         ; ARM-LABEL: t15:<br>
        -; ARM: mov     [[REG:r[0-9]+]], #2<br>
        +; ARM: mov     [[REG:r[0-9]+]], #3<br>
         ; ARM: cmp     r0, #8<br>
        -; ARM: movwgt  [[REG:r[0-9]+]], #1<br>
        -; ARM: eor     r0, [[REG:r[0-9]+]], #1<br>
        +; ARM: movwgt  [[REG:r[0-9]+]], #0<br>
<br>
         ; T2-LABEL: t15:<br>
        -; T2: movs    [[REG:r[0-9]+]], #2<br>
        +; T2: movs    [[REG:r[0-9]+]], #3<br>
         ; T2: cmp     [[REG:r[0-9]+]], #8<br>
         ; T2: it      gt<br>
        -; T2: movgt   [[REG:r[0-9]+]], #1<br>
        -; T2: eor     r0, [[REG:r[0-9]+]], #1<br>
        +; T2: movgt   [[REG:r[0-9]+]], #0<br>
           %cmp = icmp sgt i32 %p, 8<br>
           %a = select i1 %cmp, i32 1, i32 2<br>
           %xor = xor i32 %a, 1<br>
<br>
        Modified: llvm/trunk/test/CodeGen/PowerP<wbr>C/select_const.ll<br>
        URL:<br>
        <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/select_const.ll?rev=296699&r1=296698&r2=296699&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>PowerPC/select_const.ll?rev=29<wbr>6699&r1=296698&r2=296699&view=<wbr>diff</a><br>
        <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/select_const.ll?rev=296699&r1=296698&r2=296699&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/test/CodeGen<wbr>/PowerPC/select_const.ll?rev=2<wbr>96699&r1=296698&r2=296699&view<wbr>=diff</a>><br>
        ==============================<wbr>==============================<wbr>==================<br>
        --- llvm/trunk/test/CodeGen/PowerP<wbr>C/select_const.ll (original)<br>
        +++ llvm/trunk/test/CodeGen/PowerP<wbr>C/select_const.ll Wed Mar  1<br>
        16:51:31 2017<br>
        @@ -435,23 +435,20 @@ define i8 @sel_constants_add_constant(i1<br>
         ; ISEL-LABEL: sel_constants_add_constant:<br>
         ; ISEL:       # BB#0:<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        +; ISEL-NEXT:    li 4, 1<br>
        +; ISEL-NEXT:    li 3, 28<br>
         ; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    addi 3, 3, 5<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_add_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        +; NO_ISEL-NEXT:    li 4, 1<br>
        +; NO_ISEL-NEXT:    li 3, 28<br>
         ; NO_ISEL-NEXT:    bc 12, 1, .LBB21_1<br>
        -; NO_ISEL-NEXT:    b .LBB21_2<br>
        +; NO_ISEL-NEXT:    blr<br>
         ; NO_ISEL-NEXT:  .LBB21_1:<br>
         ; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB21_2:<br>
        -; NO_ISEL-NEXT:    addi 3, 3, 5<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = add i8 %sel, 5<br>
        @@ -461,24 +458,24 @@ define i8 @sel_constants_add_constant(i1<br>
         define i8 @sel_constants_sub_constant(i1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_sub_constant:<br>
         ; ISEL:       # BB#0:<br>
        +; ISEL-NEXT:    li 4, 0<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        -; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    addi 3, 3, -5<br>
        +; ISEL-NEXT:    oris 3, 4, 65535<br>
        +; ISEL-NEXT:    li 4, 18<br>
        +; ISEL-NEXT:    ori 3, 3, 65527<br>
        +; ISEL-NEXT:    isel 3, 3, 4, 1<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_sub_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        +; NO_ISEL-NEXT:    li 4, 0<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB22_1<br>
        -; NO_ISEL-NEXT:    b .LBB22_2<br>
        -; NO_ISEL-NEXT:  .LBB22_1:<br>
        -; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB22_2:<br>
        -; NO_ISEL-NEXT:    addi 3, 3, -5<br>
        +; NO_ISEL-NEXT:    oris 3, 4, 65535<br>
        +; NO_ISEL-NEXT:    li 4, 18<br>
        +; NO_ISEL-NEXT:    ori 3, 3, 65527<br>
        +; NO_ISEL-NEXT:    bclr 12, 1, 0<br>
        +; NO_ISEL-NEXT:  # BB#1:<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 0<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = sub i8 %sel, 5<br>
        @@ -488,24 +485,24 @@ define i8 @sel_constants_sub_constant(i1<br>
         define i8 @sel_constants_mul_constant(i1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_mul_constant:<br>
         ; ISEL:       # BB#0:<br>
        +; ISEL-NEXT:    lis 4, 16383<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        -; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    mulli 3, 3, 5<br>
        +; ISEL-NEXT:    ori 3, 4, 65531<br>
        +; ISEL-NEXT:    li 4, 115<br>
        +; ISEL-NEXT:    sldi 3, 3, 2<br>
        +; ISEL-NEXT:    isel 3, 3, 4, 1<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_mul_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        +; NO_ISEL-NEXT:    lis 4, 16383<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB23_1<br>
        -; NO_ISEL-NEXT:    b .LBB23_2<br>
        -; NO_ISEL-NEXT:  .LBB23_1:<br>
        -; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB23_2:<br>
        -; NO_ISEL-NEXT:    mulli 3, 3, 5<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 65531<br>
        +; NO_ISEL-NEXT:    li 4, 115<br>
        +; NO_ISEL-NEXT:    sldi 3, 3, 2<br>
        +; NO_ISEL-NEXT:    bclr 12, 1, 0<br>
        +; NO_ISEL-NEXT:  # BB#1:<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 0<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = mul i8 %sel, 5<br>
        @@ -516,33 +513,18 @@ define i8 @sel_constants_sdiv_constant(i<br>
         ; ISEL-LABEL: sel_constants_sdiv_constant:<br>
         ; ISEL:       # BB#0:<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    lis 5, 26214<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        -; ISEL-NEXT:    ori 12, 5, 26215<br>
        -; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    mulld 3, 3, 12<br>
        -; ISEL-NEXT:    rldicl 4, 3, 1, 63<br>
        -; ISEL-NEXT:    sradi 3, 3, 33<br>
        -; ISEL-NEXT:    add 3, 3, 4<br>
        +; ISEL-NEXT:    li 3, 4<br>
        +; ISEL-NEXT:    isel 3, 0, 3, 1<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_sdiv_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    lis 5, 26214<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        -; NO_ISEL-NEXT:    ori 12, 5, 26215<br>
        +; NO_ISEL-NEXT:    li 3, 4<br>
         ; NO_ISEL-NEXT:    bc 12, 1, .LBB24_1<br>
        -; NO_ISEL-NEXT:    b .LBB24_2<br>
        +; NO_ISEL-NEXT:    blr<br>
         ; NO_ISEL-NEXT:  .LBB24_1:<br>
        -; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB24_2:<br>
        -; NO_ISEL-NEXT:    mulld 3, 3, 12<br>
        -; NO_ISEL-NEXT:    rldicl 4, 3, 1, 63<br>
        -; NO_ISEL-NEXT:    sradi 3, 3, 33<br>
        -; NO_ISEL-NEXT:    add 3, 3, 4<br>
        +; NO_ISEL-NEXT:    addi 3, 0, 0<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = sdiv i8 %sel, 5<br>
        @@ -552,38 +534,21 @@ define i8 @sel_constants_sdiv_constant(i<br>
         define i8 @sel_constants_udiv_constant(i<wbr>1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_udiv_constant:<br>
         ; ISEL:       # BB#0:<br>
        -; ISEL-NEXT:    lis 4, 16383<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 5, 0<br>
        -; ISEL-NEXT:    ori 3, 4, 65535<br>
        -; ISEL-NEXT:    li 4, 23<br>
        -; ISEL-NEXT:    oris 12, 5, 52428<br>
        -; ISEL-NEXT:    sldi 3, 3, 2<br>
        -; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        -; ISEL-NEXT:    ori 4, 12, 52429<br>
        -; ISEL-NEXT:    clrldi 3, 3, 56<br>
        -; ISEL-NEXT:    mulld 3, 3, 4<br>
        -; ISEL-NEXT:    rldicl 3, 3, 30, 34<br>
        +; ISEL-NEXT:    li 4, 50<br>
        +; ISEL-NEXT:    li 3, 4<br>
        +; ISEL-NEXT:    isel 3, 4, 3, 1<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_udiv_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        -; NO_ISEL-NEXT:    lis 4, 16383<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 5, 0<br>
        -; NO_ISEL-NEXT:    ori 3, 4, 65535<br>
        -; NO_ISEL-NEXT:    li 4, 23<br>
        -; NO_ISEL-NEXT:    oris 12, 5, 52428<br>
        -; NO_ISEL-NEXT:    sldi 3, 3, 2<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB25_2<br>
        -; NO_ISEL-NEXT:  # BB#1:<br>
        -; NO_ISEL-NEXT:    ori 3, 4, 0<br>
        -; NO_ISEL-NEXT:    b .LBB25_2<br>
        -; NO_ISEL-NEXT:  .LBB25_2:<br>
        -; NO_ISEL-NEXT:    ori 4, 12, 52429<br>
        -; NO_ISEL-NEXT:    clrldi 3, 3, 56<br>
        -; NO_ISEL-NEXT:    mulld 3, 3, 4<br>
        -; NO_ISEL-NEXT:    rldicl 3, 3, 30, 34<br>
        +; NO_ISEL-NEXT:    li 4, 50<br>
        +; NO_ISEL-NEXT:    li 3, 4<br>
        +; NO_ISEL-NEXT:    bc 12, 1, .LBB25_1<br>
        +; NO_ISEL-NEXT:    blr<br>
        +; NO_ISEL-NEXT:  .LBB25_1:<br>
        +; NO_ISEL-NEXT:    addi 3, 4, 0<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = udiv i8 %sel, 5<br>
        @@ -593,40 +558,24 @@ define i8 @sel_constants_udiv_constant(i<br>
         define i8 @sel_constants_srem_constant(i<wbr>1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_srem_constant:<br>
         ; ISEL:       # BB#0:<br>
        +; ISEL-NEXT:    lis 4, 16383<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    lis 12, 26214<br>
        -; ISEL-NEXT:    li 3, 23<br>
        -; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    ori 4, 12, 26215<br>
        -; ISEL-NEXT:    extsw 3, 3<br>
        -; ISEL-NEXT:    mulld 4, 3, 4<br>
        -; ISEL-NEXT:    rldicl 5, 4, 1, 63<br>
        -; ISEL-NEXT:    sradi 4, 4, 33<br>
        -; ISEL-NEXT:    add 4, 4, 5<br>
        -; ISEL-NEXT:    mulli 4, 4, 5<br>
        -; ISEL-NEXT:    subf 3, 4, 3<br>
        +; ISEL-NEXT:    ori 3, 4, 65535<br>
        +; ISEL-NEXT:    li 4, 3<br>
        +; ISEL-NEXT:    sldi 3, 3, 2<br>
        +; ISEL-NEXT:    isel 3, 3, 4, 1<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_srem_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        +; NO_ISEL-NEXT:    lis 4, 16383<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    lis 12, 26214<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB26_1<br>
        -; NO_ISEL-NEXT:    b .LBB26_2<br>
        -; NO_ISEL-NEXT:  .LBB26_1:<br>
        -; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB26_2:<br>
        -; NO_ISEL-NEXT:    ori 4, 12, 26215<br>
        -; NO_ISEL-NEXT:    extsw 3, 3<br>
        -; NO_ISEL-NEXT:    mulld 4, 3, 4<br>
        -; NO_ISEL-NEXT:    rldicl 5, 4, 1, 63<br>
        -; NO_ISEL-NEXT:    sradi 4, 4, 33<br>
        -; NO_ISEL-NEXT:    add 4, 4, 5<br>
        -; NO_ISEL-NEXT:    mulli 4, 4, 5<br>
        -; NO_ISEL-NEXT:    subf 3, 4, 3<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 65535<br>
        +; NO_ISEL-NEXT:    li 4, 3<br>
        +; NO_ISEL-NEXT:    sldi 3, 3, 2<br>
        +; NO_ISEL-NEXT:    bclr 12, 1, 0<br>
        +; NO_ISEL-NEXT:  # BB#1:<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 0<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = srem i8 %sel, 5<br>
        @@ -637,39 +586,20 @@ define i8 @sel_constants_urem_constant(i<br>
         ; ISEL-LABEL: sel_constants_urem_constant:<br>
         ; ISEL:       # BB#0:<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 12, 0<br>
        -; ISEL-NEXT:    li 3, 23<br>
        +; ISEL-NEXT:    li 4, 2<br>
        +; ISEL-NEXT:    li 3, 3<br>
         ; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    oris 4, 12, 52428<br>
        -; ISEL-NEXT:    rlwinm 3, 3, 0, 24, 31<br>
        -; ISEL-NEXT:    ori 4, 4, 52429<br>
        -; ISEL-NEXT:    clrldi 5, 3, 32<br>
        -; ISEL-NEXT:    mulld 4, 5, 4<br>
        -; ISEL-NEXT:    rldicl 4, 4, 30, 34<br>
        -; ISEL-NEXT:    mulli 4, 4, 5<br>
        -; ISEL-NEXT:    subf 3, 4, 3<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_urem_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 12, 0<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        +; NO_ISEL-NEXT:    li 4, 2<br>
        +; NO_ISEL-NEXT:    li 3, 3<br>
         ; NO_ISEL-NEXT:    bc 12, 1, .LBB27_1<br>
        -; NO_ISEL-NEXT:    b .LBB27_2<br>
        +; NO_ISEL-NEXT:    blr<br>
         ; NO_ISEL-NEXT:  .LBB27_1:<br>
         ; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB27_2:<br>
        -; NO_ISEL-NEXT:    oris 4, 12, 52428<br>
        -; NO_ISEL-NEXT:    rlwinm 3, 3, 0, 24, 31<br>
        -; NO_ISEL-NEXT:    ori 4, 4, 52429<br>
        -; NO_ISEL-NEXT:    clrldi 5, 3, 32<br>
        -; NO_ISEL-NEXT:    mulld 4, 5, 4<br>
        -; NO_ISEL-NEXT:    rldicl 4, 4, 30, 34<br>
        -; NO_ISEL-NEXT:    mulli 4, 4, 5<br>
        -; NO_ISEL-NEXT:    subf 3, 4, 3<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = urem i8 %sel, 5<br>
        @@ -679,28 +609,21 @@ define i8 @sel_constants_urem_constant(i<br>
         define i8 @sel_constants_and_constant(i1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_and_constant:<br>
         ; ISEL:       # BB#0:<br>
        -; ISEL-NEXT:    lis 4, 16383<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    ori 3, 4, 65535<br>
        -; ISEL-NEXT:    li 4, 23<br>
        -; ISEL-NEXT:    sldi 3, 3, 2<br>
        -; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        -; ISEL-NEXT:    andi. 3, 3, 5<br>
        +; ISEL-NEXT:    li 4, 4<br>
        +; ISEL-NEXT:    li 3, 5<br>
        +; ISEL-NEXT:    isel 3, 4, 3, 1<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_and_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        -; NO_ISEL-NEXT:    lis 4, 16383<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    ori 3, 4, 65535<br>
        -; NO_ISEL-NEXT:    li 4, 23<br>
        -; NO_ISEL-NEXT:    sldi 3, 3, 2<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB28_2<br>
        -; NO_ISEL-NEXT:  # BB#1:<br>
        -; NO_ISEL-NEXT:    ori 3, 4, 0<br>
        -; NO_ISEL-NEXT:    b .LBB28_2<br>
        -; NO_ISEL-NEXT:  .LBB28_2:<br>
        -; NO_ISEL-NEXT:    andi. 3, 3, 5<br>
        +; NO_ISEL-NEXT:    li 4, 4<br>
        +; NO_ISEL-NEXT:    li 3, 5<br>
        +; NO_ISEL-NEXT:    bc 12, 1, .LBB28_1<br>
        +; NO_ISEL-NEXT:    blr<br>
        +; NO_ISEL-NEXT:  .LBB28_1:<br>
        +; NO_ISEL-NEXT:    addi 3, 4, 0<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = and i8 %sel, 5<br>
        @@ -710,28 +633,24 @@ define i8 @sel_constants_and_constant(i1<br>
         define i8 @sel_constants_or_constant(i1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_or_constant:<br>
         ; ISEL:       # BB#0:<br>
        -; ISEL-NEXT:    lis 4, 16383<br>
        +; ISEL-NEXT:    li 4, 0<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    ori 3, 4, 65535<br>
        +; ISEL-NEXT:    oris 3, 4, 65535<br>
         ; ISEL-NEXT:    li 4, 23<br>
        -; ISEL-NEXT:    sldi 3, 3, 2<br>
        +; ISEL-NEXT:    ori 3, 3, 65533<br>
         ; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        -; ISEL-NEXT:    ori 3, 3, 5<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_or_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        -; NO_ISEL-NEXT:    lis 4, 16383<br>
        +; NO_ISEL-NEXT:    li 4, 0<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    ori 3, 4, 65535<br>
        +; NO_ISEL-NEXT:    oris 3, 4, 65535<br>
         ; NO_ISEL-NEXT:    li 4, 23<br>
        -; NO_ISEL-NEXT:    sldi 3, 3, 2<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB29_2<br>
        +; NO_ISEL-NEXT:    ori 3, 3, 65533<br>
        +; NO_ISEL-NEXT:    bclr 12, 1, 0<br>
         ; NO_ISEL-NEXT:  # BB#1:<br>
         ; NO_ISEL-NEXT:    ori 3, 4, 0<br>
        -; NO_ISEL-NEXT:    b .LBB29_2<br>
        -; NO_ISEL-NEXT:  .LBB29_2:<br>
        -; NO_ISEL-NEXT:    ori 3, 3, 5<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = or i8 %sel, 5<br>
        @@ -741,28 +660,24 @@ define i8 @sel_constants_or_constant(i1<br>
         define i8 @sel_constants_xor_constant(i1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_xor_constant:<br>
         ; ISEL:       # BB#0:<br>
        -; ISEL-NEXT:    lis 4, 16383<br>
        +; ISEL-NEXT:    li 4, 0<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    ori 3, 4, 65535<br>
        -; ISEL-NEXT:    li 4, 23<br>
        -; ISEL-NEXT:    sldi 3, 3, 2<br>
        +; ISEL-NEXT:    oris 3, 4, 65535<br>
        +; ISEL-NEXT:    li 4, 18<br>
        +; ISEL-NEXT:    ori 3, 3, 65529<br>
         ; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        -; ISEL-NEXT:    xori 3, 3, 5<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_xor_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        -; NO_ISEL-NEXT:    lis 4, 16383<br>
        +; NO_ISEL-NEXT:    li 4, 0<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    ori 3, 4, 65535<br>
        -; NO_ISEL-NEXT:    li 4, 23<br>
        -; NO_ISEL-NEXT:    sldi 3, 3, 2<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB30_2<br>
        +; NO_ISEL-NEXT:    oris 3, 4, 65535<br>
        +; NO_ISEL-NEXT:    li 4, 18<br>
        +; NO_ISEL-NEXT:    ori 3, 3, 65529<br>
        +; NO_ISEL-NEXT:    bclr 12, 1, 0<br>
         ; NO_ISEL-NEXT:  # BB#1:<br>
         ; NO_ISEL-NEXT:    ori 3, 4, 0<br>
        -; NO_ISEL-NEXT:    b .LBB30_2<br>
        -; NO_ISEL-NEXT:  .LBB30_2:<br>
        -; NO_ISEL-NEXT:    xori 3, 3, 5<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = xor i8 %sel, 5<br>
        @@ -772,24 +687,29 @@ define i8 @sel_constants_xor_constant(i1<br>
         define i8 @sel_constants_shl_constant(i1 %cond) {<br>
         ; ISEL-LABEL: sel_constants_shl_constant:<br>
         ; ISEL:       # BB#0:<br>
        +; ISEL-NEXT:    lis 5, 511<br>
        +; ISEL-NEXT:    lis 4, 2047<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        +; ISEL-NEXT:    ori 3, 4, 65535<br>
        +; ISEL-NEXT:    ori 12, 5, 65535<br>
        +; ISEL-NEXT:    sldi 3, 3, 5<br>
        +; ISEL-NEXT:    sldi 4, 12, 7<br>
         ; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    slwi 3, 3, 5<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_shl_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
        +; NO_ISEL-NEXT:    lis 5, 511<br>
        +; NO_ISEL-NEXT:    lis 4, 2047<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 65535<br>
        +; NO_ISEL-NEXT:    ori 12, 5, 65535<br>
        +; NO_ISEL-NEXT:    sldi 3, 3, 5<br>
        +; NO_ISEL-NEXT:    sldi 4, 12, 7<br>
         ; NO_ISEL-NEXT:    bc 12, 1, .LBB31_1<br>
        -; NO_ISEL-NEXT:    b .LBB31_2<br>
        +; NO_ISEL-NEXT:    blr<br>
         ; NO_ISEL-NEXT:  .LBB31_1:<br>
         ; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB31_2:<br>
        -; NO_ISEL-NEXT:    slwi 3, 3, 5<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = shl i8 %sel, 5<br>
        @@ -800,23 +720,20 @@ define i8 @sel_constants_lshr_constant(i<br>
         ; ISEL-LABEL: sel_constants_lshr_constant:<br>
         ; ISEL:       # BB#0:<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        +; ISEL-NEXT:    li 4, 7<br>
        +; ISEL-NEXT:    li 3, 0<br>
         ; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    rlwinm 3, 3, 27, 29, 31<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
         ; NO_ISEL-LABEL: sel_constants_lshr_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        +; NO_ISEL-NEXT:    li 4, 7<br>
        +; NO_ISEL-NEXT:    li 3, 0<br>
         ; NO_ISEL-NEXT:    bc 12, 1, .LBB32_1<br>
        -; NO_ISEL-NEXT:    b .LBB32_2<br>
        +; NO_ISEL-NEXT:    blr<br>
         ; NO_ISEL-NEXT:  .LBB32_1:<br>
         ; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB32_2:<br>
        -; NO_ISEL-NEXT:    rlwinm 3, 3, 27, 29, 31<br>
         ; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, i8 -4, i8 23<br>
           %bo = lshr i8 %sel, 5<br>
        @@ -824,127 +741,135 @@ define i8 @sel_constants_lshr_constant(i<br>
         }<br>
<br>
         define i8 @sel_constants_ashr_constant(i<wbr>1 %cond) {<br>
        -; ISEL-LABEL: sel_constants_ashr_constant:<br>
        +; ALL-LABEL: sel_constants_ashr_constant:<br>
        +; ALL:       # BB#0:<br>
        +; ALL-NEXT:    clrldi 3, 3, 63<br>
        +; ALL-NEXT:    neg 3, 3<br>
        +; ALL-NEXT:    blr<br>
        +  %sel = select i1 %cond, i8 -4, i8 23<br>
        +  %bo = ashr i8 %sel, 5<br>
        +  ret i8 %bo<br>
        +}<br>
        +<br>
        +define double @sel_constants_fadd_constant(i<wbr>1 %cond) {<br>
        +; ISEL-LABEL: sel_constants_fadd_constant:<br>
         ; ISEL:       # BB#0:<br>
         ; ISEL-NEXT:    andi. 3, 3, 1<br>
        -; ISEL-NEXT:    li 4, -4<br>
        -; ISEL-NEXT:    li 3, 23<br>
        -; ISEL-NEXT:    isel 3, 4, 3, 1<br>
        -; ISEL-NEXT:    srawi 3, 3, 5<br>
        +; ISEL-NEXT:    addis 4, 2, .LCPI34_0@toc@ha<br>
        +; ISEL-NEXT:    addis 3, 2, .LCPI34_1@toc@ha<br>
        +; ISEL-NEXT:    addi 4, 4, .LCPI34_0@toc@l<br>
        +; ISEL-NEXT:    addi 3, 3, .LCPI34_1@toc@l<br>
        +; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        +; ISEL-NEXT:    lxsdx 1, 0, 3<br>
         ; ISEL-NEXT:    blr<br>
         ;<br>
        -; NO_ISEL-LABEL: sel_constants_ashr_constant:<br>
        +; NO_ISEL-LABEL: sel_constants_fadd_constant:<br>
         ; NO_ISEL:       # BB#0:<br>
         ; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        -; NO_ISEL-NEXT:    li 4, -4<br>
        -; NO_ISEL-NEXT:    li 3, 23<br>
        -; NO_ISEL-NEXT:    bc 12, 1, .LBB33_1<br>
        -; NO_ISEL-NEXT:    b .LBB33_2<br>
        -; NO_ISEL-NEXT:  .LBB33_1:<br>
        -; NO_ISEL-NEXT:    addi 3, 4, 0<br>
        -; NO_ISEL-NEXT:  .LBB33_2:<br>
        -; NO_ISEL-NEXT:    srawi 3, 3, 5<br>
        +; NO_ISEL-NEXT:    addis 4, 2, .LCPI34_0@toc@ha<br>
        +; NO_ISEL-NEXT:    addis 3, 2, .LCPI34_1@toc@ha<br>
        +; NO_ISEL-NEXT:    addi 4, 4, .LCPI34_0@toc@l<br>
        +; NO_ISEL-NEXT:    addi 3, 3, .LCPI34_1@toc@l<br>
        +; NO_ISEL-NEXT:    bc 12, 1, .LBB34_2<br>
        +; NO_ISEL-NEXT:  # BB#1:<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 0<br>
        +; NO_ISEL-NEXT:    b .LBB34_2<br>
        +; NO_ISEL-NEXT:  .LBB34_2:<br>
        +; NO_ISEL-NEXT:    lxsdx 1, 0, 3<br>
         ; NO_ISEL-NEXT:    blr<br>
        -  %sel = select i1 %cond, i8 -4, i8 23<br>
        -  %bo = ashr i8 %sel, 5<br>
        -  ret i8 %bo<br>
        -}<br>
        -<br>
        -define double @sel_constants_fadd_constant(i<wbr>1 %cond) {<br>
        -; ALL-LABEL: sel_constants_fadd_constant:<br>
        -; ALL:       # BB#0:<br>
        -; ALL-NEXT:    andi. 3, 3, 1<br>
        -; ALL-NEXT:    bc 12, 1, .LBB34_2<br>
        -; ALL-NEXT:  # BB#1:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI34_0@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI34_0@toc@l<br>
        -; ALL-NEXT:    lxsdx 0, 0, 3<br>
        -; ALL-NEXT:    b .LBB34_3<br>
        -; ALL-NEXT:  .LBB34_2:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI34_1@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI34_1@toc@l<br>
        -; ALL-NEXT:    lxsspx 0, 0, 3<br>
        -; ALL-NEXT:  .LBB34_3:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI34_2@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI34_2@toc@l<br>
        -; ALL-NEXT:    lxsdx 1, 0, 3<br>
        -; ALL-NEXT:    xsadddp 1, 0, 1<br>
        -; ALL-NEXT:    blr<br>
           %sel = select i1 %cond, double -4.0, double 23.3<br>
           %bo = fadd double %sel, 5.1<br>
           ret double %bo<br>
         }<br>
<br>
         define double @sel_constants_fsub_constant(i<wbr>1 %cond) {<br>
        -; ALL-LABEL: sel_constants_fsub_constant:<br>
        -; ALL:       # BB#0:<br>
        -; ALL-NEXT:    andi. 3, 3, 1<br>
        -; ALL-NEXT:    bc 12, 1, .LBB35_2<br>
        -; ALL-NEXT:  # BB#1:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI35_0@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI35_0@toc@l<br>
        -; ALL-NEXT:    lxsdx 0, 0, 3<br>
        -; ALL-NEXT:    b .LBB35_3<br>
        -; ALL-NEXT:  .LBB35_2:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI35_1@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI35_1@toc@l<br>
        -; ALL-NEXT:    lxsspx 0, 0, 3<br>
        -; ALL-NEXT:  .LBB35_3:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI35_2@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI35_2@toc@l<br>
        -; ALL-NEXT:    lxsdx 1, 0, 3<br>
        -; ALL-NEXT:    xsadddp 1, 0, 1<br>
        -; ALL-NEXT:    blr<br>
        +; ISEL-LABEL: sel_constants_fsub_constant:<br>
        +; ISEL:       # BB#0:<br>
        +; ISEL-NEXT:    andi. 3, 3, 1<br>
        +; ISEL-NEXT:    addis 4, 2, .LCPI35_0@toc@ha<br>
        +; ISEL-NEXT:    addis 3, 2, .LCPI35_1@toc@ha<br>
        +; ISEL-NEXT:    addi 4, 4, .LCPI35_0@toc@l<br>
        +; ISEL-NEXT:    addi 3, 3, .LCPI35_1@toc@l<br>
        +; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        +; ISEL-NEXT:    lxsdx 1, 0, 3<br>
        +; ISEL-NEXT:    blr<br>
        +;<br>
        +; NO_ISEL-LABEL: sel_constants_fsub_constant:<br>
        +; NO_ISEL:       # BB#0:<br>
        +; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        +; NO_ISEL-NEXT:    addis 4, 2, .LCPI35_0@toc@ha<br>
        +; NO_ISEL-NEXT:    addis 3, 2, .LCPI35_1@toc@ha<br>
        +; NO_ISEL-NEXT:    addi 4, 4, .LCPI35_0@toc@l<br>
        +; NO_ISEL-NEXT:    addi 3, 3, .LCPI35_1@toc@l<br>
        +; NO_ISEL-NEXT:    bc 12, 1, .LBB35_2<br>
        +; NO_ISEL-NEXT:  # BB#1:<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 0<br>
        +; NO_ISEL-NEXT:    b .LBB35_2<br>
        +; NO_ISEL-NEXT:  .LBB35_2:<br>
        +; NO_ISEL-NEXT:    lxsdx 1, 0, 3<br>
        +; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, double -4.0, double 23.3<br>
           %bo = fsub double %sel, 5.1<br>
           ret double %bo<br>
         }<br>
<br>
         define double @sel_constants_fmul_constant(i<wbr>1 %cond) {<br>
        -; ALL-LABEL: sel_constants_fmul_constant:<br>
        -; ALL:       # BB#0:<br>
        -; ALL-NEXT:    andi. 3, 3, 1<br>
        -; ALL-NEXT:    bc 12, 1, .LBB36_2<br>
        -; ALL-NEXT:  # BB#1:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI36_0@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI36_0@toc@l<br>
        -; ALL-NEXT:    lxsdx 0, 0, 3<br>
        -; ALL-NEXT:    b .LBB36_3<br>
        -; ALL-NEXT:  .LBB36_2:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI36_1@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI36_1@toc@l<br>
        -; ALL-NEXT:    lxsspx 0, 0, 3<br>
        -; ALL-NEXT:  .LBB36_3:<br>
        -; ALL-NEXT:    addis 3, 2, .LCPI36_2@toc@ha<br>
        -; ALL-NEXT:    addi 3, 3, .LCPI36_2@toc@l<br>
        -; ALL-NEXT:    lxsdx 1, 0, 3<br>
        -; ALL-NEXT:    xsmuldp 1, 0, 1<br>
        -; ALL-NEXT:    blr<br>
        +; ISEL-LABEL: sel_constants_fmul_constant:<br>
        +; ISEL:       # BB#0:<br>
        +; ISEL-NEXT:    andi. 3, 3, 1<br>
        +; ISEL-NEXT:    addis 4, 2, .LCPI36_0@toc@ha<br>
        +; ISEL-NEXT:    addis 3, 2, .LCPI36_1@toc@ha<br>
        +; ISEL-NEXT:    addi 4, 4, .LCPI36_0@toc@l<br>
        +; ISEL-NEXT:    addi 3, 3, .LCPI36_1@toc@l<br>
        +; ISEL-NEXT:    isel 3, 3, 4, 1<br>
        +; ISEL-NEXT:    lxsdx 1, 0, 3<br>
        +; ISEL-NEXT:    blr<br>
        +;<br>
        +; NO_ISEL-LABEL: sel_constants_fmul_constant:<br>
        +; NO_ISEL:       # BB#0:<br>
        +; NO_ISEL-NEXT:    andi. 3, 3, 1<br>
        +; NO_ISEL-NEXT:    addis 4, 2, .LCPI36_0@toc@ha<br></div></div>
        +; NO_ISEL-NEXT:    addis 3, 2, .LCPI36_1@toc@ha<br>
        +; NO_ISEL-NEXT:    addi 4, 4, .LCPI36_0@toc@l<br>
        +; NO_ISEL-NEXT:    addi 3, 3, .LCPI36_1@toc@l<br>
        +; NO_ISEL-NEXT:    bc 12, 1, .LBB36_2<span class=""><br>
        +; NO_ISEL-NEXT:  # BB#1:<br>
        +; NO_ISEL-NEXT:    ori 3, 4, 0<br></span>
        +; NO_ISEL-NEXT:    b .LBB36_2<br>
        +; NO_ISEL-NEXT:  .LBB36_2:<span class=""><br>
        +; NO_ISEL-NEXT:    lxsdx 1, 0, 3<br>
        +; NO_ISEL-NEXT:    blr<br>
           %sel = select i1 %cond, double -4.0, double 23.3<br></span>
           %bo = fmul double %sel, 5.1<br>
           ret double %bo<br>
         }</blockquote>
</blockquote></div><br></div>
</blockquote></div><br></div>