mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-20 19:04:10 -04:00
3e0f2dcf49
Summary: This is a recommit, this originally landed in rL370454 but was subsequently reverted in rL370788 due to https://bugs.llvm.org/show_bug.cgi?id=43206 The reduced testcase was added to bcmp-negative-tests.ll as @pr43206_different_loops - we must ensure that the SCEV's we got are both for the same loop we are currently investigating. Original commit message: @mclow.lists brought up this issue up in IRC. It is a reasonably common problem to compare some two values for equality. Those may be just some integers, strings or arrays of integers. In C, there is `memcmp()`, `bcmp()` functions. In C++, there exists `std::equal()` algorithm. One can also write that function manually. libstdc++'s `std::equal()` is specialized to directly call `memcmp()` for various types, but not `std::byte` from C++2a. https://godbolt.org/z/mx2ejJ libc++ does not do anything like that, it simply relies on simple C++'s `operator==()`. https://godbolt.org/z/er0Zwf (GOOD!) So likely, there exists a certain performance opportunities. Let's compare performance of naive `std::equal()` (no `memcmp()`) with one that is using `memcmp()` (in this case, compiled with modified compiler). {F8768213} ``` #include <algorithm> #include <cmath> #include <cstdint> #include <iterator> #include <limits> #include <random> #include <type_traits> #include <utility> #include <vector> #include "benchmark/benchmark.h" template <class T> bool equal(T* a, T* a_end, T* b) noexcept { for (; a != a_end; ++a, ++b) { if (*a != *b) return false; } return true; } template <typename T> std::vector<T> getVectorOfRandomNumbers(size_t count) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<T> dis(std::numeric_limits<T>::min(), std::numeric_limits<T>::max()); std::vector<T> v; v.reserve(count); std::generate_n(std::back_inserter(v), count, [&dis, &gen]() { return dis(gen); }); assert(v.size() == count); return v; } struct Identical { template <typename T> static std::pair<std::vector<T>, std::vector<T>> Gen(size_t count) { auto Tmp = getVectorOfRandomNumbers<T>(count); return std::make_pair(Tmp, std::move(Tmp)); } }; struct InequalHalfway { template <typename T> static std::pair<std::vector<T>, std::vector<T>> Gen(size_t count) { auto V0 = getVectorOfRandomNumbers<T>(count); auto V1 = V0; V1[V1.size() / size_t(2)]++; // just change the value. return std::make_pair(std::move(V0), std::move(V1)); } }; template <class T, class Gen> void BM_bcmp(benchmark::State& state) { const size_t Length = state.range(0); const std::pair<std::vector<T>, std::vector<T>> Data = Gen::template Gen<T>(Length); const std::vector<T>& a = Data.first; const std::vector<T>& b = Data.second; assert(a.size() == Length && b.size() == a.size()); benchmark::ClobberMemory(); benchmark::DoNotOptimize(a); benchmark::DoNotOptimize(a.data()); benchmark::DoNotOptimize(b); benchmark::DoNotOptimize(b.data()); for (auto _ : state) { const bool is_equal = equal(a.data(), a.data() + a.size(), b.data()); benchmark::DoNotOptimize(is_equal); } state.SetComplexityN(Length); state.counters["eltcnt"] = benchmark::Counter(Length, benchmark::Counter::kIsIterationInvariant); state.counters["eltcnt/sec"] = benchmark::Counter(Length, benchmark::Counter::kIsIterationInvariantRate); const size_t BytesRead = 2 * sizeof(T) * Length; state.counters["bytes_read/iteration"] = benchmark::Counter(BytesRead, benchmark::Counter::kDefaults, benchmark::Counter::OneK::kIs1024); state.counters["bytes_read/sec"] = benchmark::Counter( BytesRead, benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024); } template <typename T> static void CustomArguments(benchmark::internal::Benchmark* b) { const size_t L2SizeBytes = []() { for (const benchmark::CPUInfo::CacheInfo& I : benchmark::CPUInfo::Get().caches) { if (I.level == 2) return I.size; } return 0; }(); // What is the largest range we can check to always fit within given L2 cache? const size_t MaxLen = L2SizeBytes / /*total bufs*/ 2 / /*maximal elt size*/ sizeof(T) / /*safety margin*/ 2; b->RangeMultiplier(2)->Range(1, MaxLen)->Complexity(benchmark::oN); } BENCHMARK_TEMPLATE(BM_bcmp, uint8_t, Identical) ->Apply(CustomArguments<uint8_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint16_t, Identical) ->Apply(CustomArguments<uint16_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint32_t, Identical) ->Apply(CustomArguments<uint32_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint64_t, Identical) ->Apply(CustomArguments<uint64_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint8_t, InequalHalfway) ->Apply(CustomArguments<uint8_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint16_t, InequalHalfway) ->Apply(CustomArguments<uint16_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint32_t, InequalHalfway) ->Apply(CustomArguments<uint32_t>); BENCHMARK_TEMPLATE(BM_bcmp, uint64_t, InequalHalfway) ->Apply(CustomArguments<uint64_t>); ``` {F8768210} ``` $ ~/src/googlebenchmark/tools/compare.py --no-utest benchmarks build-{old,new}/test/llvm-bcmp-bench RUNNING: build-old/test/llvm-bcmp-bench --benchmark_out=/tmp/tmpb6PEUx 2019-04-25 21:17:11 Running build-old/test/llvm-bcmp-bench Run on (8 X 4000 MHz CPU s) CPU Caches: L1 Data 16K (x8) L1 Instruction 64K (x4) L2 Unified 2048K (x4) L3 Unified 8192K (x1) Load Average: 0.65, 3.90, 4.14 --------------------------------------------------------------------------------------------------- Benchmark Time CPU Iterations UserCounters... --------------------------------------------------------------------------------------------------- <...> BM_bcmp<uint8_t, Identical>/512000 432131 ns 432101 ns 1613 bytes_read/iteration=1000k bytes_read/sec=2.20706G/s eltcnt=825.856M eltcnt/sec=1.18491G/s BM_bcmp<uint8_t, Identical>_BigO 0.86 N 0.86 N BM_bcmp<uint8_t, Identical>_RMS 8 % 8 % <...> BM_bcmp<uint16_t, Identical>/256000 161408 ns 161409 ns 4027 bytes_read/iteration=1000k bytes_read/sec=5.90843G/s eltcnt=1030.91M eltcnt/sec=1.58603G/s BM_bcmp<uint16_t, Identical>_BigO 0.67 N 0.67 N BM_bcmp<uint16_t, Identical>_RMS 25 % 25 % <...> BM_bcmp<uint32_t, Identical>/128000 81497 ns 81488 ns 8415 bytes_read/iteration=1000k bytes_read/sec=11.7032G/s eltcnt=1077.12M eltcnt/sec=1.57078G/s BM_bcmp<uint32_t, Identical>_BigO 0.71 N 0.71 N BM_bcmp<uint32_t, Identical>_RMS 42 % 42 % <...> BM_bcmp<uint64_t, Identical>/64000 50138 ns 50138 ns 10909 bytes_read/iteration=1000k bytes_read/sec=19.0209G/s eltcnt=698.176M eltcnt/sec=1.27647G/s BM_bcmp<uint64_t, Identical>_BigO 0.84 N 0.84 N BM_bcmp<uint64_t, Identical>_RMS 27 % 27 % <...> BM_bcmp<uint8_t, InequalHalfway>/512000 192405 ns 192392 ns 3638 bytes_read/iteration=1000k bytes_read/sec=4.95694G/s eltcnt=1.86266G eltcnt/sec=2.66124G/s BM_bcmp<uint8_t, InequalHalfway>_BigO 0.38 N 0.38 N BM_bcmp<uint8_t, InequalHalfway>_RMS 3 % 3 % <...> BM_bcmp<uint16_t, InequalHalfway>/256000 127858 ns 127860 ns 5477 bytes_read/iteration=1000k bytes_read/sec=7.45873G/s eltcnt=1.40211G eltcnt/sec=2.00219G/s BM_bcmp<uint16_t, InequalHalfway>_BigO 0.50 N 0.50 N BM_bcmp<uint16_t, InequalHalfway>_RMS 0 % 0 % <...> BM_bcmp<uint32_t, InequalHalfway>/128000 49140 ns 49140 ns 14281 bytes_read/iteration=1000k bytes_read/sec=19.4072G/s eltcnt=1.82797G eltcnt/sec=2.60478G/s BM_bcmp<uint32_t, InequalHalfway>_BigO 0.40 N 0.40 N BM_bcmp<uint32_t, InequalHalfway>_RMS 18 % 18 % <...> BM_bcmp<uint64_t, InequalHalfway>/64000 32101 ns 32099 ns 21786 bytes_read/iteration=1000k bytes_read/sec=29.7101G/s eltcnt=1.3943G eltcnt/sec=1.99381G/s BM_bcmp<uint64_t, InequalHalfway>_BigO 0.50 N 0.50 N BM_bcmp<uint64_t, InequalHalfway>_RMS 1 % 1 % RUNNING: build-new/test/llvm-bcmp-bench --benchmark_out=/tmp/tmpQ46PP0 2019-04-25 21:19:29 Running build-new/test/llvm-bcmp-bench Run on (8 X 4000 MHz CPU s) CPU Caches: L1 Data 16K (x8) L1 Instruction 64K (x4) L2 Unified 2048K (x4) L3 Unified 8192K (x1) Load Average: 1.01, 2.85, 3.71 --------------------------------------------------------------------------------------------------- Benchmark Time CPU Iterations UserCounters... --------------------------------------------------------------------------------------------------- <...> BM_bcmp<uint8_t, Identical>/512000 18593 ns 18590 ns 37565 bytes_read/iteration=1000k bytes_read/sec=51.2991G/s eltcnt=19.2333G eltcnt/sec=27.541G/s BM_bcmp<uint8_t, Identical>_BigO 0.04 N 0.04 N BM_bcmp<uint8_t, Identical>_RMS 37 % 37 % <...> BM_bcmp<uint16_t, Identical>/256000 18950 ns 18948 ns 37223 bytes_read/iteration=1000k bytes_read/sec=50.3324G/s eltcnt=9.52909G eltcnt/sec=13.511G/s BM_bcmp<uint16_t, Identical>_BigO 0.08 N 0.08 N BM_bcmp<uint16_t, Identical>_RMS 34 % 34 % <...> BM_bcmp<uint32_t, Identical>/128000 18627 ns 18627 ns 37895 bytes_read/iteration=1000k bytes_read/sec=51.198G/s eltcnt=4.85056G eltcnt/sec=6.87168G/s BM_bcmp<uint32_t, Identical>_BigO 0.16 N 0.16 N BM_bcmp<uint32_t, Identical>_RMS 35 % 35 % <...> BM_bcmp<uint64_t, Identical>/64000 18855 ns 18855 ns 37458 bytes_read/iteration=1000k bytes_read/sec=50.5791G/s eltcnt=2.39731G eltcnt/sec=3.3943G/s BM_bcmp<uint64_t, Identical>_BigO 0.32 N 0.32 N BM_bcmp<uint64_t, Identical>_RMS 33 % 33 % <...> BM_bcmp<uint8_t, InequalHalfway>/512000 9570 ns 9569 ns 73500 bytes_read/iteration=1000k bytes_read/sec=99.6601G/s eltcnt=37.632G eltcnt/sec=53.5046G/s BM_bcmp<uint8_t, InequalHalfway>_BigO 0.02 N 0.02 N BM_bcmp<uint8_t, InequalHalfway>_RMS 29 % 29 % <...> BM_bcmp<uint16_t, InequalHalfway>/256000 9547 ns 9547 ns 74343 bytes_read/iteration=1000k bytes_read/sec=99.8971G/s eltcnt=19.0318G eltcnt/sec=26.8159G/s BM_bcmp<uint16_t, InequalHalfway>_BigO 0.04 N 0.04 N BM_bcmp<uint16_t, InequalHalfway>_RMS 29 % 29 % <...> BM_bcmp<uint32_t, InequalHalfway>/128000 9396 ns 9394 ns 73521 bytes_read/iteration=1000k bytes_read/sec=101.518G/s eltcnt=9.41069G eltcnt/sec=13.6255G/s BM_bcmp<uint32_t, InequalHalfway>_BigO 0.08 N 0.08 N BM_bcmp<uint32_t, InequalHalfway>_RMS 30 % 30 % <...> BM_bcmp<uint64_t, InequalHalfway>/64000 9499 ns 9498 ns 73802 bytes_read/iteration=1000k bytes_read/sec=100.405G/s eltcnt=4.72333G eltcnt/sec=6.73808G/s BM_bcmp<uint64_t, InequalHalfway>_BigO 0.16 N 0.16 N BM_bcmp<uint64_t, InequalHalfway>_RMS 28 % 28 % Comparing build-old/test/llvm-bcmp-bench to build-new/test/llvm-bcmp-bench Benchmark Time CPU Time Old Time New CPU Old CPU New --------------------------------------------------------------------------------------------------------------------------------------- <...> BM_bcmp<uint8_t, Identical>/512000 -0.9570 -0.9570 432131 18593 432101 18590 <...> BM_bcmp<uint16_t, Identical>/256000 -0.8826 -0.8826 161408 18950 161409 18948 <...> BM_bcmp<uint32_t, Identical>/128000 -0.7714 -0.7714 81497 18627 81488 18627 <...> BM_bcmp<uint64_t, Identical>/64000 -0.6239 -0.6239 50138 18855 50138 18855 <...> BM_bcmp<uint8_t, InequalHalfway>/512000 -0.9503 -0.9503 192405 9570 192392 9569 <...> BM_bcmp<uint16_t, InequalHalfway>/256000 -0.9253 -0.9253 127858 9547 127860 9547 <...> BM_bcmp<uint32_t, InequalHalfway>/128000 -0.8088 -0.8088 49140 9396 49140 9394 <...> BM_bcmp<uint64_t, InequalHalfway>/64000 -0.7041 -0.7041 32101 9499 32099 9498 ``` What can we tell from the benchmark? * Performance of naive equality check somewhat improves with element size, maxing out at eltcnt/sec=1.58603G/s for uint16_t, or bytes_read/sec=19.0209G/s for uint64_t. I think, that instability implies performance problems. * Performance of `memcmp()`-aware benchmark always maxes out at around bytes_read/sec=51.2991G/s for every type. That is 2.6x the throughput of the naive variant! * eltcnt/sec metric for the `memcmp()`-aware benchmark maxes out at eltcnt/sec=27.541G/s for uint8_t (was: eltcnt/sec=1.18491G/s, so 24x) and linearly decreases with element size. For uint64_t, it's ~4x+ the elements/second. * The call obvious is more pricey than the loop, with small element count. As it can be seen from the full output {F8768210}, the `memcmp()` is almost universally worse, independent of the element size (and thus buffer size) when element count is less than 8. So all in all, bcmp idiom does indeed pose untapped performance headroom. This diff does implement said idiom recognition. I think a reasonable test coverage is present, but do tell if there is anything obvious missing. Now, quality. This does succeed to build and pass the test-suite, at least without any non-bundled elements. {F8768216} {F8768217} This transform fires 91 times: ``` $ /build/test-suite/utils/compare.py -m loop-idiom.NumBCmp result-new.json Tests: 1149 Metric: loop-idiom.NumBCmp Program result-new MultiSourc...Benchmarks/7zip/7zip-benchmark 79.00 MultiSource/Applications/d/make_dparser 3.00 SingleSource/UnitTests/vla 2.00 MultiSource/Applications/Burg/burg 1.00 MultiSourc.../Applications/JM/lencod/lencod 1.00 MultiSource/Applications/lemon/lemon 1.00 MultiSource/Benchmarks/Bullet/bullet 1.00 MultiSourc...e/Benchmarks/MallocBench/gs/gs 1.00 MultiSourc...gs-C/TimberWolfMC/timberwolfmc 1.00 MultiSourc...Prolangs-C/simulator/simulator 1.00 ``` The size changes are: I'm not sure what's going on with SingleSource/UnitTests/vla.test yet, did not look. ``` $ /build/test-suite/utils/compare.py -m size..text result-{old,new}.json --filter-hash Tests: 1149 Same hash: 907 (filtered out) Remaining: 242 Metric: size..text Program result-old result-new diff test-suite...ingleSource/UnitTests/vla.test 753.00 833.00 10.6% test-suite...marks/7zip/7zip-benchmark.test 1001697.00 966657.00 -3.5% test-suite...ngs-C/simulator/simulator.test 32369.00 32321.00 -0.1% test-suite...plications/d/make_dparser.test 89585.00 89505.00 -0.1% test-suite...ce/Applications/Burg/burg.test 40817.00 40785.00 -0.1% test-suite.../Applications/lemon/lemon.test 47281.00 47249.00 -0.1% test-suite...TimberWolfMC/timberwolfmc.test 250065.00 250113.00 0.0% test-suite...chmarks/MallocBench/gs/gs.test 149889.00 149873.00 -0.0% test-suite...ications/JM/lencod/lencod.test 769585.00 769569.00 -0.0% test-suite.../Benchmarks/Bullet/bullet.test 770049.00 770049.00 0.0% test-suite...HMARK_ANISTROPIC_DIFFUSION/128 NaN NaN nan% test-suite...HMARK_ANISTROPIC_DIFFUSION/256 NaN NaN nan% test-suite...CHMARK_ANISTROPIC_DIFFUSION/64 NaN NaN nan% test-suite...CHMARK_ANISTROPIC_DIFFUSION/32 NaN NaN nan% test-suite...ENCHMARK_BILATERAL_FILTER/64/4 NaN NaN nan% Geomean difference nan% result-old result-new diff count 1.000000e+01 10.00000 10.000000 mean 3.152090e+05 311695.40000 0.006749 std 3.790398e+05 372091.42232 0.036605 min 7.530000e+02 833.00000 -0.034981 25% 4.243300e+04 42401.00000 -0.000866 50% 1.197370e+05 119689.00000 -0.000392 75% 6.397050e+05 639705.00000 -0.000005 max 1.001697e+06 966657.00000 0.106242 ``` I don't have timings though. And now to the code. The basic idea is to completely replace the whole loop. If we can't fully kill it, don't transform. I have left one or two comments in the code, so hopefully it can be understood. Also, there is a few TODO's that i have left for follow-ups: * widening of `memcmp()`/`bcmp()` * step smaller than the comparison size * Metadata propagation * more than two blocks as long as there is still a single backedge? * ??? Reviewers: reames, fhahn, mkazantsev, chandlerc, craig.topper, courbet Reviewed By: courbet Subscribers: miyuki, hiraditya, xbolva00, nikic, jfb, gchatelet, courbet, llvm-commits, mclow.lists Tags: #llvm Differential Revision: https://reviews.llvm.org/D61144 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374662 91177308-0d34-0410-b5e6-96231b3b80d8
1761 lines
87 KiB
LLVM
1761 lines
87 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -loop-idiom -verify -verify-each -verify-dom-info -verify-loop-info < %s -S | FileCheck %s
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
|
|
; This only tests various forms of loop control-flow.
|
|
; These tests are fully identical to bcmp()==0 otherwise.
|
|
|
|
; #include <algorithm>
|
|
;
|
|
; bool pointer_iteration_const_size_no_overlap(char const* ptr) {
|
|
; return std::equal(ptr, ptr + 8, ptr + 8);
|
|
; }
|
|
; bool pointer_iteration_const_size_partial_overlap(char const* ptr) {
|
|
; return std::equal(ptr, ptr + 16, ptr + 8);
|
|
; }
|
|
; bool pointer_iteration_const_size_overlap_unknown(char const* ptr0, char const* ptr1) {
|
|
; return std::equal(ptr0, ptr0 + 8, ptr1);
|
|
; }
|
|
;
|
|
; bool pointer_iteration_variable_size_no_overlap(char const* ptr, size_t count) {
|
|
; return std::equal(ptr, ptr + count, ptr + count);
|
|
; }
|
|
; bool pointer_iteration_variable_size_partial_overlap(char const* ptr, size_t count) {
|
|
; return std::equal(ptr, ptr + 2 * count, ptr + count);
|
|
; }
|
|
; bool pointer_iteration_variable_size_overlap_unknown(char const* ptr0, char const* ptr1, size_t count) {
|
|
; return std::equal(ptr0, ptr0 + count, ptr1);
|
|
; }
|
|
;
|
|
; bool index_iteration_eq_const_size_no_overlap(char const* ptr) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + 8;
|
|
; for(size_t i = 0; i < 8; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool index_iteration_eq_const_size_partial_overlap(char const* ptr) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + 8;
|
|
; for(size_t i = 0; i < 16; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool index_iteration_eq_const_size_overlap_unknown(char const* ptr0, char const* ptr1) {
|
|
; for(size_t i = 0; i < 8; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; bool index_iteration_eq_variable_size_no_overlap(char const* ptr, size_t count) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + count;
|
|
; for(size_t i = 0; i < count; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool index_iteration_eq_variable_size_partial_overlap(char const* ptr, size_t count) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + count;
|
|
; for(size_t i = 0; i < 2 * count; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool index_iteration_eq_variable_size_overlap_unknown(char const* ptr0, char const* ptr1, size_t count) {
|
|
; for(size_t i = 0; i < count; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; bool index_iteration_starting_from_negative(char const* ptr0, char const* ptr1) {
|
|
; for(int i = -4; i < 4; i++) {
|
|
; if(ptr0[i] != ptr1[i])
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; bool combined_iteration_eq_const_size_no_overlap(char const* ptr) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + 8;
|
|
; for(size_t i = 0; i < 8; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool combined_iteration_eq_const_size_partial_overlap(char const* ptr) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + 8;
|
|
; for(size_t i = 0; i < 16; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool combined_iteration_eq_const_size_overlap_unknown(char const* ptr0, char const* ptr1) {
|
|
; for(size_t i = 0; i < 8; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; bool combined_iteration_eq_variable_size_no_overlap(char const* ptr, size_t count) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + count;
|
|
; for(size_t i = 0; i < count; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool combined_iteration_eq_variable_size_partial_overlap(char const* ptr, size_t count) {
|
|
; char const* ptr0 = ptr;
|
|
; char const* ptr1 = ptr + count;
|
|
; for(size_t i = 0; i < 2 * count; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
; bool combined_iteration_eq_variable_size_overlap_unknown(char const* ptr0, char const* ptr1, size_t count) {
|
|
; for(size_t i = 0; i < count; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; bool negated_pointer_iteration_variable_size_overlap_unknown(char const* ptr0, char const* ptr1, size_t count) {
|
|
; return !std::equal(ptr0, ptr0 + count, ptr1);
|
|
; }
|
|
;
|
|
; bool integer_pointer_iteration_variable_size_overlap_unknown(int const* ptr0, int const* ptr1, size_t count) {
|
|
; return std::equal(ptr0, ptr0 + count, ptr1);
|
|
; }
|
|
;
|
|
; bool small_index_iteration(char const* ptr0, char const* ptr1, int count) {
|
|
; for(int i = 0; i < count; i++, ++ptr0, ++ptr1) {
|
|
; if(*ptr0 != *ptr1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; bool three_pointer_iteration(char const* ptr0, char const* ptr0_end, char const* ptr1) {
|
|
; return std::equal(ptr0, ptr0_end, ptr1);
|
|
; }
|
|
;
|
|
; int value_propagation(char const* ptr0, char const* ptr1, size_t count, int on_equal, int on_unequal) {
|
|
; if(std::equal(ptr0, ptr0 + count, ptr1))
|
|
; return on_equal;
|
|
; return on_unequal;
|
|
; }
|
|
;
|
|
; void callee_on_unequal();
|
|
; void callee_on_success();
|
|
; void multiple_exit_blocks(char const* ptr0, char const* ptr1, size_t count) {
|
|
; if(!std::equal(ptr0, ptr0 + count, ptr1)) {
|
|
; callee_on_unequal();
|
|
; return;
|
|
; }
|
|
; callee_on_success();
|
|
; }
|
|
;
|
|
; void multiple_phis(char const* ptr0, char const* ptr1, size_t count, char const* v0, char const* v1, char const* v2, char const* v3, char const** out0, char const** out1) {
|
|
; char const *o0, *o1;
|
|
; if(std::equal(ptr0, ptr0 + count, ptr1)) {
|
|
; o0 = v0;
|
|
; o1 = v1;
|
|
; } else {
|
|
; o0 = v2;
|
|
; o1 = v3;
|
|
; }
|
|
; *out0 = o0;
|
|
; *out1 = o1;
|
|
; }
|
|
;
|
|
; void sink(bool);
|
|
; void loop_within_loop(size_t outer_count, char const** ptr0, char const** ptr1, size_t* count) {
|
|
; for(size_t i = 0; i != outer_count; ++i)
|
|
; sink(std::equal(ptr0[i], ptr0[i] + count[i], ptr1[i]));
|
|
; }
|
|
;
|
|
; void loop_within_loop_with_multiple_exit_blocks(size_t outer_count, char const** ptr0, char const** ptr1, size_t* count) {
|
|
; for(size_t i = 0; i != outer_count; ++i) {
|
|
; if(!std::equal(ptr0[i], ptr0[i] + count[i], ptr1[i])) {
|
|
; callee_on_unequal();
|
|
; return;
|
|
; }
|
|
; callee_on_success();
|
|
; }
|
|
; }
|
|
;
|
|
; void endless_loop_if_equal(int *a, int *b) {
|
|
; for (;;) {
|
|
; for (int c = 0; c < 4; c++) {
|
|
; if (a[c] != b[c])
|
|
; return;
|
|
; }
|
|
; }
|
|
; }
|
|
;
|
|
; bool load_of_bitcasts(char const* ptr0, float const* ptr1, size_t count) {
|
|
; for(size_t i = 0; i < count; i++, ptr0 += sizeof(float), ptr1++) {
|
|
; int v0, v1;
|
|
; memcpy(&v0, ptr0, sizeof(float));
|
|
; memcpy(&v1, ptr1, sizeof(float));
|
|
; if(v0 != v1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
;
|
|
; // FIXME
|
|
; bool overlapping_loads(char const* ptr0, char const* ptr1, size_t count) {
|
|
; for(size_t i = 0; i < count; i++, ptr0++, ptr1++) {
|
|
; int v0, v1;
|
|
; memcpy(&v0, ptr0, sizeof(float));
|
|
; memcpy(&v1, ptr1, sizeof(float));
|
|
; if(v0 != v1)
|
|
; return false;
|
|
; }
|
|
; return true;
|
|
; }
|
|
|
|
define i1 @_Z39pointer_iteration_const_size_no_overlapPKc(i8* %ptr) {
|
|
; CHECK-LABEL: @_Z39pointer_iteration_const_size_no_overlapPKc(
|
|
; CHECK-NEXT: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 8
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 8)
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 8
|
|
br label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %for.inc.i.i, %entry
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %add.ptr, %entry ]
|
|
%__first1.addr.06.i.i.idx = phi i64 [ %__first1.addr.06.i.i.add, %for.inc.i.i ], [ 0, %entry ]
|
|
%__first1.addr.06.i.i.ptr = getelementptr inbounds i8, i8* %ptr, i64 %__first1.addr.06.i.i.idx
|
|
%v0 = load i8, i8* %__first1.addr.06.i.i.ptr
|
|
%v1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %v0, %v1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%__first1.addr.06.i.i.add = add nuw nsw i64 %__first1.addr.06.i.i.idx, 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i64 %__first1.addr.06.i.i.add, 8
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i
|
|
%retval.0.i.i = phi i1 [ false, %for.body.i.i ], [ true, %for.inc.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z44pointer_iteration_const_size_partial_overlapPKc(i8* %ptr) {
|
|
; CHECK-LABEL: @_Z44pointer_iteration_const_size_partial_overlapPKc(
|
|
; CHECK-NEXT: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 8
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR1]], i64 16)
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR1_EQCMP]], label [[PTR_VS_ADD_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%add.ptr1 = getelementptr inbounds i8, i8* %ptr, i64 8
|
|
br label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %for.inc.i.i, %entry
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %add.ptr1, %entry ]
|
|
%__first1.addr.06.i.i.idx = phi i64 [ %__first1.addr.06.i.i.add, %for.inc.i.i ], [ 0, %entry ]
|
|
%__first1.addr.06.i.i.ptr = getelementptr inbounds i8, i8* %ptr, i64 %__first1.addr.06.i.i.idx
|
|
%v0 = load i8, i8* %__first1.addr.06.i.i.ptr
|
|
%v1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %v0, %v1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%__first1.addr.06.i.i.add = add nuw nsw i64 %__first1.addr.06.i.i.idx, 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i64 %__first1.addr.06.i.i.add, 16
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i
|
|
%retval.0.i.i = phi i1 [ false, %for.body.i.i ], [ true, %for.inc.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z44pointer_iteration_const_size_overlap_unknownPKcS0_(i8* %ptr0, i8* %ptr1) {
|
|
; CHECK-LABEL: @_Z44pointer_iteration_const_size_overlap_unknownPKcS0_(
|
|
; CHECK-NEXT: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 8)
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
br label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %for.inc.i.i, %entry
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i.idx = phi i64 [ %__first1.addr.06.i.i.add, %for.inc.i.i ], [ 0, %entry ]
|
|
%__first1.addr.06.i.i.ptr = getelementptr inbounds i8, i8* %ptr0, i64 %__first1.addr.06.i.i.idx
|
|
%v0 = load i8, i8* %__first1.addr.06.i.i.ptr
|
|
%v1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %v0, %v1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%__first1.addr.06.i.i.add = add nuw nsw i64 %__first1.addr.06.i.i.idx, 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i64 %__first1.addr.06.i.i.add, 8
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i
|
|
%retval.0.i.i = phi i1 [ false, %for.body.i.i ], [ true, %for.inc.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z42pointer_iteration_variable_size_no_overlapPKcm(i8* %ptr, i64 %count) {
|
|
; CHECK-LABEL: @_Z42pointer_iteration_variable_size_no_overlapPKcm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %add.ptr, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr, %entry ]
|
|
%v0 = load i8, i8* %__first1.addr.06.i.i
|
|
%v1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %v0, %v1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %entry
|
|
%retval.0.i.i = phi i1 [ true, %entry ], [ true, %for.inc.i.i ], [ false, %for.body.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z47pointer_iteration_variable_size_partial_overlapPKcm(i8* %ptr, i64 %count) {
|
|
; CHECK-LABEL: @_Z47pointer_iteration_variable_size_partial_overlapPKcm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[MUL_BYTECOUNT:%.*]] = shl i64 [[COUNT:%.*]], 1
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[MUL_BYTECOUNT]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[MUL_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[COUNT]]
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR1]], i64 [[MUL_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR1_EQCMP]], label [[PTR_VS_ADD_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%mul = shl i64 %count, 1
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 %mul
|
|
%cmp5.i.i = icmp eq i64 %mul, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i.preheader
|
|
|
|
for.body.i.i.preheader: ; preds = %entry
|
|
%add.ptr1 = getelementptr inbounds i8, i8* %ptr, i64 %count
|
|
br label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %for.body.i.i.preheader, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %add.ptr1, %for.body.i.i.preheader ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr, %for.body.i.i.preheader ]
|
|
%v0 = load i8, i8* %__first1.addr.06.i.i
|
|
%v1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %v0, %v1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %entry
|
|
%retval.0.i.i = phi i1 [ true, %entry ], [ true, %for.inc.i.i ], [ false, %for.body.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z47pointer_iteration_variable_size_overlap_unknownPKcS0_m(i8* %ptr0, i8* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z47pointer_iteration_variable_size_overlap_unknownPKcS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR0:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr0, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%v0 = load i8, i8* %__first1.addr.06.i.i
|
|
%v1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %v0, %v1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %entry
|
|
%retval.0.i.i = phi i1 [ true, %entry ], [ true, %for.inc.i.i ], [ false, %for.body.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z40index_iteration_eq_const_size_no_overlapPKc(i8* %ptr) {
|
|
; CHECK-LABEL: @_Z40index_iteration_eq_const_size_no_overlapPKc(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 8
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 8)
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 8
|
|
br label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp ult i64 %inc, 8
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%i.013 = phi i64 [ 0, %entry ], [ %inc, %for.cond ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %i.013
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %add.ptr, i64 %i.013
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw nsw i64 %i.013, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.cond, %for.body
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.cond ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z45index_iteration_eq_const_size_partial_overlapPKc(i8* %ptr) {
|
|
; CHECK-LABEL: @_Z45index_iteration_eq_const_size_partial_overlapPKc(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 8
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 16)
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 8
|
|
br label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp ult i64 %inc, 16
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%i.013 = phi i64 [ 0, %entry ], [ %inc, %for.cond ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %i.013
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %add.ptr, i64 %i.013
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw nsw i64 %i.013, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.cond, %for.body
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.cond ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z45index_iteration_eq_const_size_overlap_unknownPKcS0_(i8* %ptr0, i8* %ptr1) {
|
|
; CHECK-LABEL: @_Z45index_iteration_eq_const_size_overlap_unknownPKcS0_(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 8)
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp ult i64 %inc, 8
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%i.08 = phi i64 [ 0, %entry ], [ %inc, %for.cond ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr0, i64 %i.08
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %ptr1, i64 %i.08
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw nsw i64 %i.08, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.cond, %for.body
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.cond ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z43index_iteration_eq_variable_size_no_overlapPKcm(i8* %ptr, i64 %count) {
|
|
; CHECK-LABEL: @_Z43index_iteration_eq_variable_size_no_overlapPKcm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP14:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP14]], label [[CLEANUP:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 %count
|
|
%cmp14 = icmp eq i64 %count, 0
|
|
br i1 %cmp14, label %cleanup, label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp ult i64 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%i.015 = phi i64 [ %inc, %for.cond ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %i.015
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %add.ptr, i64 %i.015
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw i64 %i.015, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.cond, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.cond ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z48index_iteration_eq_variable_size_partial_overlapPKcm(i8* %ptr, i64 %count) {
|
|
; CHECK-LABEL: @_Z48index_iteration_eq_variable_size_partial_overlapPKcm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[COUNT:%.*]]
|
|
; CHECK-NEXT: [[MUL_BYTECOUNT:%.*]] = shl i64 [[COUNT]], 1
|
|
; CHECK-NEXT: [[CMP14:%.*]] = icmp eq i64 [[MUL_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP14]], label [[CLEANUP:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 [[MUL_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 %count
|
|
%mul = shl i64 %count, 1
|
|
%cmp14 = icmp eq i64 %mul, 0
|
|
br i1 %cmp14, label %cleanup, label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp ult i64 %inc, %mul
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%i.015 = phi i64 [ %inc, %for.cond ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %i.015
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %add.ptr, i64 %i.015
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw i64 %i.015, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.cond, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.cond ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z48index_iteration_eq_variable_size_overlap_unknownPKcS0_m(i8* %ptr0, i8* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z48index_iteration_eq_variable_size_overlap_unknownPKcS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP8:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP8]], label [[CLEANUP:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%cmp8 = icmp eq i64 %count, 0
|
|
br i1 %cmp8, label %cleanup, label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp ult i64 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%i.09 = phi i64 [ %inc, %for.cond ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr0, i64 %i.09
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %ptr1, i64 %i.09
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw i64 %i.09, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.cond, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.cond ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z38index_iteration_starting_from_negativePKcS0_(i8* %ptr0, i8* %ptr1) {
|
|
; CHECK-LABEL: @_Z38index_iteration_starting_from_negativePKcS0_(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PTR0:%.*]], i64 -4
|
|
; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, i8* [[PTR1:%.*]], i64 -4
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[SCEVGEP]], i8* [[SCEVGEP1]], i64 8)
|
|
; CHECK-NEXT: [[SCEVGEP_VS_SCEVGEP1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[SCEVGEP_VS_SCEVGEP1_EQCMP]], label [[SCEVGEP_VS_SCEVGEP1_EQCMP_EQUALBB:%.*]], label [[SCEVGEP_VS_SCEVGEP1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: scevgep.vs.scevgep1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: scevgep.vs.scevgep1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RET:%.*]] = phi i1 [ false, [[SCEVGEP_VS_SCEVGEP1_EQCMP_UNEQUALBB]] ], [ true, [[SCEVGEP_VS_SCEVGEP1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.cond: ; preds = %for.body
|
|
%cmp = icmp slt i64 %indvars.iv.next, 4
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.cond
|
|
%indvars.iv = phi i64 [ -4, %entry ], [ %indvars.iv.next, %for.cond ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr0, i64 %indvars.iv
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx2 = getelementptr inbounds i8, i8* %ptr1, i64 %indvars.iv
|
|
%v1 = load i8, i8* %arrayidx2
|
|
%cmp4 = icmp eq i8 %v0, %v1
|
|
%indvars.iv.next = add nsw i64 %indvars.iv, 1
|
|
br i1 %cmp4, label %for.cond, label %cleanup
|
|
|
|
cleanup: ; preds = %for.cond, %for.body
|
|
%ret = phi i1 [ false, %for.body ], [ true, %for.cond ]
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @_Z43combined_iteration_eq_const_size_no_overlapPKc(i8* %ptr) {
|
|
; CHECK-LABEL: @_Z43combined_iteration_eq_const_size_no_overlapPKc(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 8
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 8)
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 8
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%i.015 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%ptr1.014 = phi i8* [ %add.ptr, %entry ], [ %incdec.ptr3, %for.inc ]
|
|
%ptr0.013 = phi i8* [ %ptr, %entry ], [ %incdec.ptr, %for.inc ]
|
|
%v0 = load i8, i8* %ptr0.013
|
|
%v1 = load i8, i8* %ptr1.014
|
|
%cmp2 = icmp eq i8 %v0, %v1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw nsw i64 %i.015, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.013, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.014, i64 1
|
|
%cmp = icmp ult i64 %inc, 8
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.inc, %for.body
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.inc ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z48combined_iteration_eq_const_size_partial_overlapPKc(i8* %ptr) {
|
|
; CHECK-LABEL: @_Z48combined_iteration_eq_const_size_partial_overlapPKc(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 8
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 16)
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 8
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%i.015 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%ptr1.014 = phi i8* [ %add.ptr, %entry ], [ %incdec.ptr3, %for.inc ]
|
|
%ptr0.013 = phi i8* [ %ptr, %entry ], [ %incdec.ptr, %for.inc ]
|
|
%v0 = load i8, i8* %ptr0.013
|
|
%v1 = load i8, i8* %ptr1.014
|
|
%cmp2 = icmp eq i8 %v0, %v1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw nsw i64 %i.015, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.013, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.014, i64 1
|
|
%cmp = icmp ult i64 %inc, 16
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.inc, %for.body
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.inc ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z48combined_iteration_eq_const_size_overlap_unknownPKcS0_(i8* %ptr0, i8* %ptr1) {
|
|
; CHECK-LABEL: @_Z48combined_iteration_eq_const_size_overlap_unknownPKcS0_(
|
|
; CHECK-NEXT: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 8)
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%i.010 = phi i64 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%ptr1.addr.09 = phi i8* [ %ptr1, %entry ], [ %incdec.ptr3, %for.inc ]
|
|
%ptr0.addr.08 = phi i8* [ %ptr0, %entry ], [ %incdec.ptr, %for.inc ]
|
|
%v0 = load i8, i8* %ptr0.addr.08
|
|
%v1 = load i8, i8* %ptr1.addr.09
|
|
%cmp2 = icmp eq i8 %v0, %v1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw nsw i64 %i.010, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.addr.08, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.addr.09, i64 1
|
|
%cmp = icmp ult i64 %inc, 8
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.inc, %for.body
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.inc ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z46combined_iteration_eq_variable_size_no_overlapPKcm(i8* %ptr, i64 %count) {
|
|
; CHECK-LABEL: @_Z46combined_iteration_eq_variable_size_no_overlapPKcm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP14:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP14]], label [[CLEANUP:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[COUNT_BYTECOUNT]]
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%cmp14 = icmp eq i64 %count, 0
|
|
br i1 %cmp14, label %cleanup, label %for.body.preheader
|
|
|
|
for.body.preheader: ; preds = %entry
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 %count
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %for.body.preheader, %for.inc
|
|
%i.017 = phi i64 [ %inc, %for.inc ], [ 0, %for.body.preheader ]
|
|
%ptr1.016 = phi i8* [ %incdec.ptr3, %for.inc ], [ %add.ptr, %for.body.preheader ]
|
|
%ptr0.015 = phi i8* [ %incdec.ptr, %for.inc ], [ %ptr, %for.body.preheader ]
|
|
%v0 = load i8, i8* %ptr0.015
|
|
%v1 = load i8, i8* %ptr1.016
|
|
%cmp2 = icmp eq i8 %v0, %v1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw i64 %i.017, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.015, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.016, i64 1
|
|
%cmp = icmp ult i64 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.inc, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.inc ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z51combined_iteration_eq_variable_size_partial_overlapPKcm(i8* %ptr, i64 %count) {
|
|
; CHECK-LABEL: @_Z51combined_iteration_eq_variable_size_partial_overlapPKcm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[MUL_BYTECOUNT:%.*]] = shl i64 [[COUNT:%.*]], 1
|
|
; CHECK-NEXT: [[CMP14:%.*]] = icmp eq i64 [[MUL_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP14]], label [[CLEANUP:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR:%.*]], i64 [[COUNT]]
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR]], i8* [[ADD_PTR]], i64 [[MUL_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR_VS_ADD_PTR_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR_VS_ADD_PTR_EQCMP]], label [[PTR_VS_ADD_PTR_EQCMP_EQUALBB:%.*]], label [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr.vs.add.ptr.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR_VS_ADD_PTR_EQCMP_UNEQUALBB]] ], [ true, [[PTR_VS_ADD_PTR_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%mul = shl i64 %count, 1
|
|
%cmp14 = icmp eq i64 %mul, 0
|
|
br i1 %cmp14, label %cleanup, label %for.body.preheader
|
|
|
|
for.body.preheader: ; preds = %entry
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr, i64 %count
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %for.body.preheader, %for.inc
|
|
%i.017 = phi i64 [ %inc, %for.inc ], [ 0, %for.body.preheader ]
|
|
%ptr1.016 = phi i8* [ %incdec.ptr3, %for.inc ], [ %add.ptr, %for.body.preheader ]
|
|
%ptr0.015 = phi i8* [ %incdec.ptr, %for.inc ], [ %ptr, %for.body.preheader ]
|
|
%v0 = load i8, i8* %ptr0.015
|
|
%v1 = load i8, i8* %ptr1.016
|
|
%cmp2 = icmp eq i8 %v0, %v1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw i64 %i.017, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.015, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.016, i64 1
|
|
%cmp = icmp ult i64 %inc, %mul
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.inc, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.inc ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z51combined_iteration_eq_variable_size_overlap_unknownPKcS0_m(i8* %ptr0, i8* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z51combined_iteration_eq_variable_size_overlap_unknownPKcS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP8:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP8]], label [[CLEANUP:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%cmp8 = icmp eq i64 %count, 0
|
|
br i1 %cmp8, label %cleanup, label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%i.011 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
|
|
%ptr1.addr.010 = phi i8* [ %incdec.ptr3, %for.inc ], [ %ptr1, %entry ]
|
|
%ptr0.addr.09 = phi i8* [ %incdec.ptr, %for.inc ], [ %ptr0, %entry ]
|
|
%v0 = load i8, i8* %ptr0.addr.09
|
|
%v1 = load i8, i8* %ptr1.addr.010
|
|
%cmp2 = icmp eq i8 %v0, %v1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw i64 %i.011, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.addr.09, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.addr.010, i64 1
|
|
%cmp = icmp ult i64 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.inc, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.inc ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @_Z55negated_pointer_iteration_variable_size_overlap_unknownPKcS0_m(i8* %ptr0, i8* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z55negated_pointer_iteration_variable_size_overlap_unknownPKcS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR0:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ true, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ false, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr0, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%t0 = load i8, i8* %__first1.addr.06.i.i
|
|
%t1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t0, %t1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %entry
|
|
%retval.0.i.i = phi i1 [ false, %entry ], [ false, %for.inc.i.i ], [ true, %for.body.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z55integer_pointer_iteration_variable_size_overlap_unknownPKiS0_m(i32* %ptr0, i32* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z55integer_pointer_iteration_variable_size_overlap_unknownPKiS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[PTR0:%.*]], i64 [[COUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKIS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = shl nsw i64 [[COUNT]], 2
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], -4
|
|
; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 2
|
|
; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP2]], 2
|
|
; CHECK-NEXT: [[DOTBYTECOUNT:%.*]] = add i64 [[TMP3]], 4
|
|
; CHECK-NEXT: [[CSTR:%.*]] = bitcast i32* [[PTR0]] to i8*
|
|
; CHECK-NEXT: [[CSTR1:%.*]] = bitcast i32* [[PTR1:%.*]] to i8*
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[CSTR]], i8* [[CSTR1]], i64 [[DOTBYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKIS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKIS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKiS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKIS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKiS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKIS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i32, i32* %ptr0, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKiS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i32* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i32* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%t0 = load i32, i32* %__first1.addr.06.i.i
|
|
%t1 = load i32, i32* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i32 %t0, %t1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKiS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i32, i32* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i32, i32* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i32* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKiS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKiS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %entry
|
|
%retval.0.i.i = phi i1 [ true, %entry ], [ true, %for.inc.i.i ], [ false, %for.body.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i1 @_Z21small_index_iterationPKcS0_i(i8* %ptr0, i8* %ptr1, i32 %count) {
|
|
; CHECK-LABEL: @_Z21small_index_iterationPKcS0_i(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[COUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP8]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]], label [[CLEANUP:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[DOTBYTECOUNT:%.*]] = zext i32 [[COUNT]] to i64
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 [[DOTBYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[T2_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[T2:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[T2_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[T2]]
|
|
;
|
|
entry:
|
|
%cmp8 = icmp sgt i32 %count, 0
|
|
br i1 %cmp8, label %for.body, label %cleanup
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%i.011 = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
|
|
%ptr1.addr.010 = phi i8* [ %incdec.ptr3, %for.inc ], [ %ptr1, %entry ]
|
|
%ptr0.addr.09 = phi i8* [ %incdec.ptr, %for.inc ], [ %ptr0, %entry ]
|
|
%t0 = load i8, i8* %ptr0.addr.09
|
|
%t1 = load i8, i8* %ptr1.addr.010
|
|
%cmp2 = icmp eq i8 %t0, %t1
|
|
br i1 %cmp2, label %for.inc, label %cleanup
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw nsw i32 %i.011, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.addr.09, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.addr.010, i64 1
|
|
%cmp = icmp slt i32 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup: ; preds = %for.body, %for.inc, %entry
|
|
%t2 = phi i1 [ true, %entry ], [ true, %for.inc ], [ false, %for.body ]
|
|
ret i1 %t2
|
|
}
|
|
|
|
define i1 @_Z23three_pointer_iterationPKcS0_S0_(i8* %ptr0, i8* %ptr0_end, i8* %ptr1) {
|
|
; CHECK-LABEL: @_Z23three_pointer_iterationPKcS0_S0_(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[PTR01:%.*]] = ptrtoint i8* [[PTR0:%.*]] to i64
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i8* [[PTR0]], [[PTR0_END:%.*]]
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = sub i64 0, [[PTR01]]
|
|
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PTR0_END]], i64 [[TMP0]]
|
|
; CHECK-NEXT: [[DOTBYTECOUNT:%.*]] = ptrtoint i8* [[SCEVGEP]] to i64
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0]], i8* [[PTR1:%.*]], i64 [[DOTBYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RETVAL_0_I_I]]
|
|
;
|
|
entry:
|
|
%cmp5.i.i = icmp eq i8* %ptr0, %ptr0_end
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%t0 = load i8, i8* %__first1.addr.06.i.i
|
|
%t1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t0, %t1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %ptr0_end
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %entry
|
|
%retval.0.i.i = phi i1 [ true, %entry ], [ true, %for.inc.i.i ], [ false, %for.body.i.i ]
|
|
ret i1 %retval.0.i.i
|
|
}
|
|
|
|
define i32 @_Z17value_propagationPKcS0_mii(i8* %ptr0, i8* %ptr1, i64 %count, i32 %on_equal, i32 %on_unequal) {
|
|
; CHECK-LABEL: @_Z17value_propagationPKcS0_mii(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR0:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[T2_PH:%.*]] = phi i32 [ [[ON_UNEQUAL:%.*]], [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ [[ON_EQUAL:%.*]], [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[T2:%.*]] = phi i32 [ [[ON_EQUAL]], [[ENTRY:%.*]] ], [ [[T2_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i32 [[T2]]
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr0, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%t0 = load i8, i8* %__first1.addr.06.i.i
|
|
%t1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t0, %t1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.inc.i.i, %for.body.i.i, %entry
|
|
%t2 = phi i32 [ %on_equal, %entry ], [ %on_equal, %for.inc.i.i ], [ %on_unequal, %for.body.i.i ]
|
|
ret i32 %t2
|
|
}
|
|
|
|
define void @_Z20multiple_exit_blocksPKcS0_m(i8* %ptr0, i8* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z20multiple_exit_blocksPKcS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR0:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[IF_END:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[IF_END_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: tail call void @_Z17callee_on_unequalv()
|
|
; CHECK-NEXT: br label [[RETURN:%.*]]
|
|
; CHECK: if.end.loopexit:
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: tail call void @_Z17callee_on_successv()
|
|
; CHECK-NEXT: br label [[RETURN]]
|
|
; CHECK: return:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr0, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %if.end, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%t0 = load i8, i8* %__first1.addr.06.i.i
|
|
%t1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t0, %t1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %if.then
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %if.end, label %for.body.i.i
|
|
|
|
if.then: ; preds = %for.body.i.i
|
|
tail call void @_Z17callee_on_unequalv()
|
|
br label %return
|
|
|
|
if.end: ; preds = %for.inc.i.i, %entry
|
|
tail call void @_Z17callee_on_successv()
|
|
br label %return
|
|
|
|
return: ; preds = %if.end, %if.then
|
|
ret void
|
|
}
|
|
declare void @_Z17callee_on_unequalv()
|
|
declare void @_Z17callee_on_successv()
|
|
|
|
define void @_Z13multiple_phisPKcS0_mS0_S0_S0_S0_PS0_S1_(i8* %ptr0, i8* %ptr1, i64 %count, i8* %v0, i8* %v1, i8* %v2, i8* %v3, i8** %out0, i8** %out1) {
|
|
; CHECK-LABEL: @_Z13multiple_phisPKcS0_mS0_S0_S0_S0_PS0_S1_(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[PTR0:%.*]], i64 [[COUNT_BYTECOUNT:%.*]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[COUNT_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0]], i8* [[PTR1:%.*]], i64 [[COUNT_BYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[T2_PH:%.*]] = phi i8* [ [[V2:%.*]], [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ [[V0:%.*]], [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: [[T3_PH:%.*]] = phi i8* [ [[V3:%.*]], [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ [[V1:%.*]], [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[T2:%.*]] = phi i8* [ [[V0]], [[ENTRY:%.*]] ], [ [[T2_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: [[T3:%.*]] = phi i8* [ [[V1]], [[ENTRY]] ], [ [[T3_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: store i8* [[T2]], i8** [[OUT0:%.*]]
|
|
; CHECK-NEXT: store i8* [[T3]], i8** [[OUT1:%.*]]
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr0, i64 %count
|
|
%cmp5.i.i = icmp eq i64 %count, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %entry, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %ptr1, %entry ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %ptr0, %entry ]
|
|
%t0 = load i8, i8* %__first1.addr.06.i.i
|
|
%t1 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t0, %t1
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.inc.i.i, %for.body.i.i, %entry
|
|
%t2 = phi i8* [ %v0, %entry ], [ %v0, %for.inc.i.i ], [ %v2, %for.body.i.i ]
|
|
%t3 = phi i8* [ %v1, %entry ], [ %v1, %for.inc.i.i ], [ %v3, %for.body.i.i ]
|
|
store i8* %t2, i8** %out0
|
|
store i8* %t3, i8** %out1
|
|
ret void
|
|
}
|
|
|
|
define void @_Z16loop_within_loopmPPKcS1_Pm(i64 %outer_count, i8** %ptr0, i8** %ptr1, i64* %count) {
|
|
; CHECK-LABEL: @_Z16loop_within_loopmPPKcS1_Pm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP11:%.*]] = icmp eq i64 [[OUTER_COUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
|
|
; CHECK: for.body.preheader:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.cond.cleanup.loopexit:
|
|
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
|
|
; CHECK: for.cond.cleanup:
|
|
; CHECK-NEXT: ret void
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[I_012:%.*]] = phi i64 [ [[INC:%.*]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
|
|
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8*, i8** [[PTR0:%.*]], i64 [[I_012]]
|
|
; CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ARRAYIDX]]
|
|
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, i64* [[COUNT:%.*]], i64 [[I_012]]
|
|
; CHECK-NEXT: [[T1_BYTECOUNT:%.*]] = load i64, i64* [[ARRAYIDX2]]
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[T1_BYTECOUNT]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[T1_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]], label [[FOR_BODY_I_I_PREHEADER:%.*]]
|
|
; CHECK: for.body.i.i.preheader:
|
|
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i8*, i8** [[PTR1:%.*]], i64 [[I_012]]
|
|
; CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARRAYIDX3]]
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[T0]], i8* [[T2]], i64 [[T1_BYTECOUNT]])
|
|
; CHECK-NEXT: [[T0_VS_T2_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: br i1 [[T0_VS_T2_EQCMP]], label [[T0_VS_T2_EQCMP_EQUALBB:%.*]], label [[T0_VS_T2_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: t0.vs.t2.eqcmp.equalbb:
|
|
; CHECK-NEXT: br i1 true, label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB]]
|
|
; CHECK: t0.vs.t2.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br i1 true, label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]], label [[FOR_BODY_I_I_BCMPDISPATCHBB]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit.loopexit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I_PH:%.*]] = phi i1 [ false, [[T0_VS_T2_EQCMP_UNEQUALBB]] ], [ true, [[T0_VS_T2_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT]]
|
|
; CHECK: _ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit:
|
|
; CHECK-NEXT: [[RETVAL_0_I_I:%.*]] = phi i1 [ true, [[FOR_BODY]] ], [ [[RETVAL_0_I_I_PH]], [[_ZNST3__15EQUALIPKCS2_EEBT_S3_T0__EXIT_LOOPEXIT]] ]
|
|
; CHECK-NEXT: tail call void @_Z4sinkb(i1 [[RETVAL_0_I_I]])
|
|
; CHECK-NEXT: [[INC]] = add nuw i64 [[I_012]], 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INC]], [[OUTER_COUNT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]
|
|
;
|
|
entry:
|
|
%cmp11 = icmp eq i64 %outer_count, 0
|
|
br i1 %cmp11, label %for.cond.cleanup, label %for.body
|
|
|
|
for.cond.cleanup: ; preds = %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, %entry
|
|
ret void
|
|
|
|
for.body: ; preds = %entry, %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
%i.012 = phi i64 [ %inc, %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i8*, i8** %ptr0, i64 %i.012
|
|
%t0 = load i8*, i8** %arrayidx
|
|
%arrayidx2 = getelementptr inbounds i64, i64* %count, i64 %i.012
|
|
%t1 = load i64, i64* %arrayidx2
|
|
%add.ptr = getelementptr inbounds i8, i8* %t0, i64 %t1
|
|
%cmp5.i.i = icmp eq i64 %t1, 0
|
|
br i1 %cmp5.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i.preheader
|
|
|
|
for.body.i.i.preheader: ; preds = %for.body
|
|
%arrayidx3 = getelementptr inbounds i8*, i8** %ptr1, i64 %i.012
|
|
%t2 = load i8*, i8** %arrayidx3
|
|
br label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %for.body.i.i.preheader, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %t2, %for.body.i.i.preheader ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %t0, %for.body.i.i.preheader ]
|
|
%t3 = load i8, i8* %__first1.addr.06.i.i
|
|
%t4 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t3, %t4
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit, label %for.body.i.i
|
|
|
|
_ZNSt3__15equalIPKcS2_EEbT_S3_T0_.exit: ; preds = %for.body.i.i, %for.inc.i.i, %for.body
|
|
%retval.0.i.i = phi i1 [ true, %for.body ], [ true, %for.inc.i.i ], [ false, %for.body.i.i ]
|
|
tail call void @_Z4sinkb(i1 %retval.0.i.i)
|
|
%inc = add nuw i64 %i.012, 1
|
|
%cmp = icmp eq i64 %inc, %outer_count
|
|
br i1 %cmp, label %for.cond.cleanup, label %for.body
|
|
}
|
|
declare void @_Z4sinkb(i1)
|
|
|
|
define void @_Z42loop_within_loop_with_multiple_exit_blocksmPPKcS1_Pm(i64 %outer_count, i8** %ptr0, i8** %ptr1, i64* %count) {
|
|
; CHECK-LABEL: @_Z42loop_within_loop_with_multiple_exit_blocksmPPKcS1_Pm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP11:%.*]] = icmp eq i64 [[OUTER_COUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP11]], label [[CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
|
|
; CHECK: for.body.preheader:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[I_012:%.*]] = phi i64 [ [[INC:%.*]], [[IF_END:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
|
|
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8*, i8** [[PTR0:%.*]], i64 [[I_012]]
|
|
; CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ARRAYIDX]]
|
|
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i64, i64* [[COUNT:%.*]], i64 [[I_012]]
|
|
; CHECK-NEXT: [[T1_BYTECOUNT:%.*]] = load i64, i64* [[ARRAYIDX2]]
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[T1_BYTECOUNT]]
|
|
; CHECK-NEXT: [[CMP5_I_I:%.*]] = icmp eq i64 [[T1_BYTECOUNT]], 0
|
|
; CHECK-NEXT: br i1 [[CMP5_I_I]], label [[IF_END]], label [[FOR_BODY_I_I_PREHEADER:%.*]]
|
|
; CHECK: for.body.i.i.preheader:
|
|
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i8*, i8** [[PTR1:%.*]], i64 [[I_012]]
|
|
; CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[ARRAYIDX3]]
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[T0]], i8* [[T2]], i64 [[T1_BYTECOUNT]])
|
|
; CHECK-NEXT: [[T0_VS_T2_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br label [[FOR_BODY_I_I_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.i.i.bcmpdispatchbb:
|
|
; CHECK-NEXT: br i1 [[T0_VS_T2_EQCMP]], label [[T0_VS_T2_EQCMP_EQUALBB:%.*]], label [[T0_VS_T2_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: t0.vs.t2.eqcmp.equalbb:
|
|
; CHECK-NEXT: br i1 true, label [[IF_END_LOOPEXIT:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB]]
|
|
; CHECK: t0.vs.t2.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[FOR_BODY_I_I_BCMPDISPATCHBB]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: tail call void @_Z17callee_on_unequalv()
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: if.end.loopexit:
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: tail call void @_Z17callee_on_successv()
|
|
; CHECK-NEXT: [[INC]] = add nuw i64 [[I_012]], 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INC]], [[OUTER_COUNT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
%cmp11 = icmp eq i64 %outer_count, 0
|
|
br i1 %cmp11, label %cleanup, label %for.body
|
|
|
|
for.body: ; preds = %entry, %if.end
|
|
%i.012 = phi i64 [ %inc, %if.end ], [ 0, %entry ]
|
|
%arrayidx = getelementptr inbounds i8*, i8** %ptr0, i64 %i.012
|
|
%t0 = load i8*, i8** %arrayidx
|
|
%arrayidx2 = getelementptr inbounds i64, i64* %count, i64 %i.012
|
|
%t1 = load i64, i64* %arrayidx2
|
|
%add.ptr = getelementptr inbounds i8, i8* %t0, i64 %t1
|
|
%cmp5.i.i = icmp eq i64 %t1, 0
|
|
br i1 %cmp5.i.i, label %if.end, label %for.body.i.i.preheader
|
|
|
|
for.body.i.i.preheader: ; preds = %for.body
|
|
%arrayidx3 = getelementptr inbounds i8*, i8** %ptr1, i64 %i.012
|
|
%t2 = load i8*, i8** %arrayidx3
|
|
br label %for.body.i.i
|
|
|
|
for.body.i.i: ; preds = %for.body.i.i.preheader, %for.inc.i.i
|
|
%__first2.addr.07.i.i = phi i8* [ %incdec.ptr1.i.i, %for.inc.i.i ], [ %t2, %for.body.i.i.preheader ]
|
|
%__first1.addr.06.i.i = phi i8* [ %incdec.ptr.i.i, %for.inc.i.i ], [ %t0, %for.body.i.i.preheader ]
|
|
%t3 = load i8, i8* %__first1.addr.06.i.i
|
|
%t4 = load i8, i8* %__first2.addr.07.i.i
|
|
%cmp.i.i.i = icmp eq i8 %t3, %t4
|
|
br i1 %cmp.i.i.i, label %for.inc.i.i, label %if.then
|
|
|
|
for.inc.i.i: ; preds = %for.body.i.i
|
|
%incdec.ptr.i.i = getelementptr inbounds i8, i8* %__first1.addr.06.i.i, i64 1
|
|
%incdec.ptr1.i.i = getelementptr inbounds i8, i8* %__first2.addr.07.i.i, i64 1
|
|
%cmp.i.i = icmp eq i8* %incdec.ptr.i.i, %add.ptr
|
|
br i1 %cmp.i.i, label %if.end, label %for.body.i.i
|
|
|
|
if.then: ; preds = %for.body.i.i
|
|
tail call void @_Z17callee_on_unequalv()
|
|
br label %cleanup
|
|
|
|
if.end: ; preds = %for.inc.i.i, %for.body
|
|
tail call void @_Z17callee_on_successv()
|
|
%inc = add nuw i64 %i.012, 1
|
|
%cmp = icmp eq i64 %inc, %outer_count
|
|
br i1 %cmp, label %cleanup, label %for.body
|
|
|
|
cleanup: ; preds = %if.end, %entry, %if.then
|
|
ret void
|
|
}
|
|
|
|
define void @_Z21endless_loop_if_equalPiS_(i32* %a, i32* %b) {
|
|
; CHECK-LABEL: @_Z21endless_loop_if_equalPiS_(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
; CHECK: for.cond.loopexit:
|
|
; CHECK-NEXT: br label [[FOR_COND]]
|
|
; CHECK: for.cond:
|
|
; CHECK-NEXT: [[CSTR:%.*]] = bitcast i32* [[A:%.*]] to i8*
|
|
; CHECK-NEXT: [[CSTR1:%.*]] = bitcast i32* [[B:%.*]] to i8*
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[CSTR]], i8* [[CSTR1]], i64 16)
|
|
; CHECK-NEXT: [[A_VS_B_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: br i1 [[A_VS_B_EQCMP]], label [[A_VS_B_EQCMP_EQUALBB:%.*]], label [[A_VS_B_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: a.vs.b.eqcmp.equalbb:
|
|
; CHECK-NEXT: br i1 true, label [[FOR_COND_LOOPEXIT:%.*]], label [[FOR_BODY_BCMPDISPATCHBB]]
|
|
; CHECK: a.vs.b.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br i1 true, label [[RETURN:%.*]], label [[FOR_BODY_BCMPDISPATCHBB]]
|
|
; CHECK: return:
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.cond1, %entry
|
|
br label %for.body
|
|
|
|
for.cond1: ; preds = %for.body
|
|
%cmp = icmp ult i64 %indvars.iv.next, 4
|
|
br i1 %cmp, label %for.body, label %for.cond
|
|
|
|
for.body: ; preds = %for.cond, %for.cond1
|
|
%indvars.iv = phi i64 [ 0, %for.cond ], [ %indvars.iv.next, %for.cond1 ]
|
|
%arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
|
|
%0 = load i32, i32* %arrayidx
|
|
%arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
|
|
%1 = load i32, i32* %arrayidx3
|
|
%cmp4 = icmp eq i32 %0, %1
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
br i1 %cmp4, label %for.cond1, label %return
|
|
|
|
return: ; preds = %for.body
|
|
ret void
|
|
}
|
|
|
|
define i1 @_Z21load_of_bitcastsPKcPKfm(i8* %ptr0, float* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z21load_of_bitcastsPKcPKfm(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP13:%.*]] = icmp eq i64 [[COUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP13]], label [[CLEANUP3:%.*]], label [[FOR_BODY_BCMPDISPATCHBB:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[DOTBYTECOUNT:%.*]] = shl nuw i64 [[COUNT]], 2
|
|
; CHECK-NEXT: [[CSTR:%.*]] = bitcast float* [[PTR1:%.*]] to i8*
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[CSTR]], i64 [[DOTBYTECOUNT]])
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP3_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP3_LOOPEXIT]]
|
|
; CHECK: cleanup3.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ], [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP3]]
|
|
; CHECK: cleanup3:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP3_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%cmp13 = icmp eq i64 %count, 0
|
|
br i1 %cmp13, label %cleanup3, label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%ptr0.addr.016 = phi i8* [ %add.ptr, %for.inc ], [ %ptr0, %entry ]
|
|
%i.015 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
|
|
%ptr1.addr.014 = phi float* [ %incdec.ptr, %for.inc ], [ %ptr1, %entry ]
|
|
%v0.0..sroa_cast = bitcast i8* %ptr0.addr.016 to i32*
|
|
%v0.0.copyload = load i32, i32* %v0.0..sroa_cast
|
|
%v1.0..sroa_cast = bitcast float* %ptr1.addr.014 to i32*
|
|
%v1.0.copyload = load i32, i32* %v1.0..sroa_cast
|
|
%cmp1 = icmp eq i32 %v0.0.copyload, %v1.0.copyload
|
|
br i1 %cmp1, label %for.inc, label %cleanup3
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw i64 %i.015, 1
|
|
%add.ptr = getelementptr inbounds i8, i8* %ptr0.addr.016, i64 4
|
|
%incdec.ptr = getelementptr inbounds float, float* %ptr1.addr.014, i64 1
|
|
%cmp = icmp ult i64 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup3
|
|
|
|
cleanup3: ; preds = %for.body, %for.inc, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.inc ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
; FIXME
|
|
define i1 @_Z17overlapping_loadsPKcS0_m(i8* %ptr0, i8* %ptr1, i64 %count) {
|
|
; CHECK-LABEL: @_Z17overlapping_loadsPKcS0_m(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP14:%.*]] = icmp eq i64 [[COUNT:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[CMP14]], label [[CLEANUP4:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
|
|
; CHECK: for.body.preheader:
|
|
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
|
|
; CHECK: for.body:
|
|
; CHECK-NEXT: [[PTR0_ADDR_017:%.*]] = phi i8* [ [[INCDEC_PTR:%.*]], [[FOR_INC:%.*]] ], [ [[PTR0:%.*]], [[FOR_BODY_PREHEADER]] ]
|
|
; CHECK-NEXT: [[I_016:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
|
|
; CHECK-NEXT: [[PTR1_ADDR_015:%.*]] = phi i8* [ [[INCDEC_PTR3:%.*]], [[FOR_INC]] ], [ [[PTR1:%.*]], [[FOR_BODY_PREHEADER]] ]
|
|
; CHECK-NEXT: [[V0_0__SROA_CAST:%.*]] = bitcast i8* [[PTR0_ADDR_017]] to i32*
|
|
; CHECK-NEXT: [[V0_0_COPYLOAD:%.*]] = load i32, i32* [[V0_0__SROA_CAST]]
|
|
; CHECK-NEXT: [[V1_0__SROA_CAST:%.*]] = bitcast i8* [[PTR1_ADDR_015]] to i32*
|
|
; CHECK-NEXT: [[V1_0_COPYLOAD:%.*]] = load i32, i32* [[V1_0__SROA_CAST]]
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[V0_0_COPYLOAD]], [[V1_0_COPYLOAD]]
|
|
; CHECK-NEXT: br i1 [[CMP1]], label [[FOR_INC]], label [[CLEANUP4_LOOPEXIT:%.*]]
|
|
; CHECK: for.inc:
|
|
; CHECK-NEXT: [[INC]] = add nuw i64 [[I_016]], 1
|
|
; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, i8* [[PTR0_ADDR_017]], i64 1
|
|
; CHECK-NEXT: [[INCDEC_PTR3]] = getelementptr inbounds i8, i8* [[PTR1_ADDR_015]], i64 1
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[INC]], [[COUNT]]
|
|
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP4_LOOPEXIT]]
|
|
; CHECK: cleanup4.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ false, [[FOR_BODY]] ], [ true, [[FOR_INC]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP4]]
|
|
; CHECK: cleanup4:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP4_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
%cmp14 = icmp eq i64 %count, 0
|
|
br i1 %cmp14, label %cleanup4, label %for.body
|
|
|
|
for.body: ; preds = %entry, %for.inc
|
|
%ptr0.addr.017 = phi i8* [ %incdec.ptr, %for.inc ], [ %ptr0, %entry ]
|
|
%i.016 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
|
|
%ptr1.addr.015 = phi i8* [ %incdec.ptr3, %for.inc ], [ %ptr1, %entry ]
|
|
%v0.0..sroa_cast = bitcast i8* %ptr0.addr.017 to i32*
|
|
%v0.0.copyload = load i32, i32* %v0.0..sroa_cast
|
|
%v1.0..sroa_cast = bitcast i8* %ptr1.addr.015 to i32*
|
|
%v1.0.copyload = load i32, i32* %v1.0..sroa_cast
|
|
%cmp1 = icmp eq i32 %v0.0.copyload, %v1.0.copyload
|
|
br i1 %cmp1, label %for.inc, label %cleanup4
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add nuw i64 %i.016, 1
|
|
%incdec.ptr = getelementptr inbounds i8, i8* %ptr0.addr.017, i64 1
|
|
%incdec.ptr3 = getelementptr inbounds i8, i8* %ptr1.addr.015, i64 1
|
|
%cmp = icmp ult i64 %inc, %count
|
|
br i1 %cmp, label %for.body, label %cleanup4
|
|
|
|
cleanup4: ; preds = %for.body, %for.inc, %entry
|
|
%res = phi i1 [ true, %entry ], [ true, %for.inc ], [ false, %for.body ]
|
|
ret i1 %res
|
|
}
|
|
|
|
define i1 @exit_block_is_not_dedicated(i8* %ptr0, i8* %ptr1) {
|
|
; CHECK-LABEL: @exit_block_is_not_dedicated(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br i1 true, label [[FOR_BODY_BCMPDISPATCHBB:%.*]], label [[CLEANUP:%.*]]
|
|
; CHECK: for.body.bcmpdispatchbb:
|
|
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* [[PTR0:%.*]], i8* [[PTR1:%.*]], i64 8)
|
|
; CHECK-NEXT: [[PTR0_VS_PTR1_EQCMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
|
; CHECK-NEXT: br i1 [[PTR0_VS_PTR1_EQCMP]], label [[PTR0_VS_PTR1_EQCMP_EQUALBB:%.*]], label [[PTR0_VS_PTR1_EQCMP_UNEQUALBB:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.equalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT:%.*]]
|
|
; CHECK: ptr0.vs.ptr1.eqcmp.unequalbb:
|
|
; CHECK-NEXT: br label [[CLEANUP_LOOPEXIT]]
|
|
; CHECK: cleanup.loopexit:
|
|
; CHECK-NEXT: [[RES_PH:%.*]] = phi i1 [ true, [[PTR0_VS_PTR1_EQCMP_EQUALBB]] ], [ false, [[PTR0_VS_PTR1_EQCMP_UNEQUALBB]] ]
|
|
; CHECK-NEXT: br label [[CLEANUP]]
|
|
; CHECK: cleanup:
|
|
; CHECK-NEXT: [[RES:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[RES_PH]], [[CLEANUP_LOOPEXIT]] ]
|
|
; CHECK-NEXT: ret i1 [[RES]]
|
|
;
|
|
entry:
|
|
br i1 true, label %for.body, label %cleanup
|
|
|
|
for.body:
|
|
%i.08 = phi i64 [ 0, %entry ], [ %inc, %for.cond ]
|
|
%arrayidx = getelementptr inbounds i8, i8* %ptr0, i64 %i.08
|
|
%v0 = load i8, i8* %arrayidx
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %ptr1, i64 %i.08
|
|
%v1 = load i8, i8* %arrayidx1
|
|
%cmp3 = icmp eq i8 %v0, %v1
|
|
%inc = add nuw nsw i64 %i.08, 1
|
|
br i1 %cmp3, label %for.cond, label %cleanup
|
|
|
|
for.cond:
|
|
%cmp = icmp ult i64 %inc, 8
|
|
br i1 %cmp, label %for.body, label %cleanup
|
|
|
|
cleanup:
|
|
%res = phi i1 [ false, %for.body ], [ true, %for.cond ], [ false, %entry ]
|
|
ret i1 %res
|
|
}
|