Perform only loop unroll using opt

LLVM version 16.0.4
System: Ubuntu 20.04.6 LTS

Hello,

I’m trying to run a simple program and use opt to have it perform only loop unrolling optimization on the associated .ll file but it doesn’t seem to be working. I assume I’m surely doing something wrong with the associated llvm IR code. I created a simple matrix vector multiplication program that I have pasted below.

#include <stdio.h>
#include <stdlib.h>

#ifndef UNROLL_FACTOR
#define UNROLL_FACTOR 1
#endif

void mat_vec(int** arrA, int* arrB, int* result, const int size )
{

    for( int i = 0; i < size; i++ ) {

        result[i] = 0;

        #pragma clang loop unroll_count(UNROLL_FACTOR)
        for( int k = 0; k < size; k++ ) {

            int t = arrA[i][k] * arrB[k];
            result[i] += t;

        }
    }

};


int main(int argc, char* argv[])
{
// check command line
  if (argc != 2) {fprintf(stderr, "USAGE: %s matrix_vector_size\n", argv[0]); exit(-1);}
  const int size = atoi(argv[1]);

    /* declarations */
    int** A      = new int* [size];
    int*  B      = new int  [size];
    int*  result = new int  [size];

    for( int i = 0; i < size; i++ )
    {
        A[i] = new int[size];
    }

    srand(1337);

    for( int i = 0; i < size; i++ )
    {
        for( int j = 0; j < size; j++ )
        {
            A[i][j] = rand();
        }
    }

    for( int i = 0; i < size; i++)
        B[i] = rand();


    mat_vec( A, B, result, size );

    for( int i = 0; i < size; i++ )
    for( int i = 0; i < size; i++ )
    {
        result[i] = result[i];
    }

    /* clean up */
    for( int i = 0; i < size; i++ )
    {
        delete [] A[i];
    }

    delete [] A;
    delete [] B;
    delete [] result;
    return 0;
};

I compile the file into llvm bitcode using optimization level 0.
I have an environment variable I pass to the file that sets the clang pragma for how many times to unroll the loop. If this isn’t passed it’s assumed that it is 1, so no unrolling.

UNROLL_FACTOR=4 clang++ -O0 -S -emit-llvm -o mat_vec.ll mat_vec.cpp

I then try and use opt on the associated file to run it through the loop unroll pass.
opt --passes=loop-unroll -S -o mat_vec_unroll.ll mat_vec.ll

However, the associated llvm IR is exactly the same as the initial compile command. I think I may have to do a few other passes to get it to unroll but wasn’t sure what the best path forward would be.

Here is a link to the resulting .ll file.
mat_vec_4_unroll.ll

Any help would be greatly appreciated.

Thanks.

See for example Writing an LLVM Pass(question about .ll file ) - #2 by EagleEyeGiggles about the optnone attribute (added by clang with O0), and how to avoid it.

I also encounter this problem before , and to adopt loop-unroll ,first you should run the -mem2reg and -loops (enable loop optimization)
you can try this :opt -mem2reg -loops -loop-simplify -loop-rotate -loop-unroll -debug
and maybe you want to set the unroll size : opt -mem2reg -loops -loop-simplify -loop-rotate -loop-unroll -debug -unroll-count=<...>

Gotcha I will do that. Thank you very much for the help!