[llvm] r296699 - [DAGCombiner] fold binops with constant into select-of-constants
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 8 08:43:15 PST 2017
This is step 2:
https://reviews.llvm.org/D30741
That should fix the example reported here.
On Mon, Mar 6, 2017 at 1:44 PM, Sanjay Patel <spatel at rotateright.com> wrote:
> Here's a first step (but doesn't fix the problem yet):
> https://reviews.llvm.org/rL297026
>
> But that led to another question:
> https://reviews.llvm.org/D30665
>
> On Mon, Mar 6, 2017 at 8:01 AM, Sanjay Patel <spatel at rotateright.com>
> wrote:
>
>> Thanks, Mikael. At first glance, we're missing this fold that exists in
>> InstSimplify in the DAGCombiner:
>>
>> // X % 0 -> undef, we don't need to preserve faults!
>>
>> That's easy to expose with this test compiled for x86-64:
>>
>> define i32 @urem0(i32 %x) {
>> %rem = urem i32 %x, 0
>> ret i32 %rem
>> }
>>
>> $ ./llc -o - urem0.ll | grep div
>> divl %ecx <--- that was a big waste of time :)
>>
>>
>> I think there's a 2nd problem for all of visitREM/SDIV/UDIV: we try a
>> bunch of combines before the easy "simplifies". Eg:
>>
>> // undef / X -> 0
>> if (N0.isUndef())
>> return DAG.getConstant(0, DL, VT);
>> // X / undef -> undef
>> if (N1.isUndef())
>> return N1;
>>
>> 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'.
>>
>> I'll try to expose this with other tests.
>>
>>
>>
>> On Mon, Mar 6, 2017 at 5:57 AM, Mikael Holmén <mikael.holmen at ericsson.com
>> > wrote:
>>
>>> Hi Sanjay,
>>>
>>> On 03/02/2017 06:46 PM, Sanjay Patel via llvm-commits wrote:
>>>
>>>> This should be fixed with:
>>>> https://reviews.llvm.org/rL296768 <https://reviews.llvm.org/rL296768>
>>>>
>>>> Please let me know if you find any other problems. Thanks!
>>>>
>>>
>>> I also found a case that triggers an assertion even with the fix.
>>>
>>> This comes from llvm-stress + bugpoint so might also be odd:
>>>
>>> llc stress_reduced.ll
>>>
>>> gives
>>>
>>> llc: ../lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1722: llvm::SDValue
>>> (anonymous namespace)::DAGCombiner::foldBinOpIntoSelect(llvm::SDNode
>>> *): Assertion `(isConstantOrConstantVector(NewCT) ||
>>> isConstantFPBuildVectorOrConstantFP(NewCT)) && "Failed to constant fold
>>> a binop with constant operands"' failed.
>>> #0 0x0000000001b482e4 PrintStackTraceSignalHandler(void*)
>>> (build-all/bin/llc+0x1b482e4)
>>> #1 0x0000000001b48a56 SignalHandler(int) (build-all/bin/llc+0x1b48a56)
>>> #2 0x00007f5310ee5330 __restore_rt (/lib/x86_64-linux-gnu/libpthr
>>> ead.so.0+0x10330)
>>> #3 0x00007f530fad8c37 gsignal /build/eglibc-oGUzwX/eglibc-2.
>>> 19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
>>> #4 0x00007f530fadc028 abort /build/eglibc-oGUzwX/eglibc-2.
>>> 19/stdlib/abort.c:91:0
>>> #5 0x00007f530fad1bf6 __assert_fail_base /build/eglibc-oGUzwX/eglibc-2.
>>> 19/assert/assert.c:92:0
>>> #6 0x00007f530fad1ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
>>> #7 0x0000000001910187 (anonymous namespace)::DAGCombiner::foldBinOpIntoSelect(llvm::SDNode*)
>>> (build-all/bin/llc+0x1910187)
>>> #8 0x00000000018b15e2 (anonymous namespace)::DAGCombiner::visit(llvm::SDNode*)
>>> (build-all/bin/llc+0x18b15e2)
>>> #9 0x00000000018afeec (anonymous namespace)::DAGCombiner::combine(llvm::SDNode*)
>>> (build-all/bin/llc+0x18afeec)
>>> #10 0x00000000018af63a llvm::SelectionDAG::Combine(llvm::CombineLevel,
>>> llvm::AAResults&, llvm::CodeGenOpt::Level) (build-all/bin/llc+0x18af63a)
>>> #11 0x0000000001a07edb llvm::SelectionDAGISel::CodeGenAndEmitDAG()
>>> (build-all/bin/llc+0x1a07edb)
>>> #12 0x0000000001a06634 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function
>>> const&) (build-all/bin/llc+0x1a06634)
>>> #13 0x0000000001a029fa llvm::SelectionDAGISel::runOnM
>>> achineFunction(llvm::MachineFunction&) (build-all/bin/llc+0x1a029fa)
>>> #14 0x0000000000f7b331 (anonymous namespace)::X86DAGToDAGISel::r
>>> unOnMachineFunction(llvm::MachineFunction&) (build-all/bin/llc+0xf7b331)
>>> #15 0x00000000013ab952 llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
>>> (build-all/bin/llc+0x13ab952)
>>> #16 0x000000000163eeb8 llvm::FPPassManager::runOnFunction(llvm::Function&)
>>> (build-all/bin/llc+0x163eeb8)
>>> #17 0x000000000163f0f8 llvm::FPPassManager::runOnModule(llvm::Module&)
>>> (build-all/bin/llc+0x163f0f8)
>>> #18 0x000000000163f5d5 llvm::legacy::PassManagerImpl::run(llvm::Module&)
>>> (build-all/bin/llc+0x163f5d5)
>>> #19 0x000000000068bf59 compileModule(char**, llvm::LLVMContext&)
>>> (build-all/bin/llc+0x68bf59)
>>> #20 0x0000000000688f4b main (build-all/bin/llc+0x688f4b)
>>> #21 0x00007f530fac3f45 __libc_start_main /build/eglibc-oGUzwX/eglibc-2.
>>> 19/csu/libc-start.c:321:0
>>> #22 0x000000000068716b _start (build-all/bin/llc+0x68716b)
>>> Stack dump:
>>> 0. Program arguments: build-all/bin/llc stress_reduced.ll
>>> 1. Running pass 'Function Pass Manager' on module
>>> 'stress_reduced.ll'.
>>> 2. Running pass 'X86 DAG->DAG Instruction Selection' on function
>>> '@autogen_SD30383'
>>> Abort
>>>
>>> Regards,
>>> Mikael
>>>
>>>
>>>> On Thu, Mar 2, 2017 at 9:00 AM, Sanjay Patel <spatel at rotateright.com
>>>> <mailto: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
>>>> <mailto: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::foldBinOpIntoSelect(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/Support/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/CodeGen/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::SelectBasicBlock(llvm::ilist_iterato
>>>> r<llvm::ilist_detail::node_options<llvm::Instruction,
>>>> true, false, void>, false, true>,
>>>> llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::
>>>> Instruction,
>>>> true, false, void>, false, true>, bool&)
>>>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/SelectionDA
>>>> GISel.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::runOnMachineFunction(llvm::MachineFu
>>>> nction&)
>>>> /work/llvm-git/build/../lib/CodeGen/SelectionDAG/SelectionDA
>>>> GISel.cpp:543:0
>>>> #19 0x00007f96cb575b86 (anonymous
>>>> namespace)::AArch64DAGToDAGISel::runOnMachineFunction(llvm::
>>>> MachineFunction&)
>>>> /work/llvm-git/build/../lib/Target/AArch64/AArch64ISelDAGToD
>>>> AG.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::BackendA
>>>> ction,
>>>> 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::HandleTranslationUnit(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:1
>>>> 61:0
>>>> #30 0x00007f96c382b3a4 clang::ASTFrontendAction::Exec
>>>> uteAction()
>>>> /work/llvm-git/build/../tools/clang/lib/Frontend/FrontendAct
>>>> ion.cpp:569:0
>>>> #31 0x00007f96c4180899 clang::CodeGenAction::ExecuteAction()
>>>> /work/llvm-git/build/../tools/clang/lib/CodeGen/CodeGenActio
>>>> n.cpp:973:0
>>>> #32 0x00007f96c382ae49 clang::FrontendAction::Execute()
>>>> /work/llvm-git/build/../tools/clang/lib/Frontend/FrontendAct
>>>> ion.cpp:472:0
>>>> #33 0x00007f96c37bff23
>>>> clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
>>>> /work/llvm-git/build/../tools/clang/lib/Frontend/CompilerIns
>>>> tance.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/clang-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
>>>> <mailto:llvm-commits-bounces at lists.llvm.org>> on behalf of
>>>> Sanjay Patel via llvm-commits <llvm-commits at lists.llvm.org
>>>> <mailto:llvm-commits at lists.llvm.org>>
>>>> *Sent:* 01 March 2017 22:51
>>>> *To:* llvm-commits at lists.llvm.org
>>>> <mailto: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
>>>> <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
>>>> <https://bugs.llvm.org/show_bug.cgi?id=32105>
>>>>
>>>> Differential Revision: https://reviews.llvm.org/D30502
>>>> <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/20
>>>> 10-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/S
>>>> electionDAG/DAGCombiner.cpp?rev=296699&r1=296698&r2=296699&view=diff
>>>> <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(OpSize
>>>> InBits)))
>>>> @@ -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(OpSizeInBits)))
>>>> @@ -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
>>>> <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
>>>> <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
>>>> }
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170308/cd6c1aa2/attachment-0001.html>
More information about the llvm-commits
mailing list