xref: /llvm-project/llvm/test/Transforms/LoopVectorize/uniform-args-call-variants.ll (revision a105877646d68e48cdeeeadd9d1e075dc3c5d68d)
184ebe5b7SGraham Hunter; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
284ebe5b7SGraham Hunter; RUN: opt < %s -passes=loop-vectorize,instcombine -force-vector-width=2 -force-vector-interleave=1 -S | FileCheck %s
384ebe5b7SGraham Hunter
484ebe5b7SGraham Hunter; A call whose argument can remain a scalar for a vectorized function variant
584ebe5b7SGraham Hunter; with a uniform argument because it's loop invariant
684ebe5b7SGraham Hunterdefine void @test_uniform(ptr noalias %dst, ptr readonly %src, i64 %uniform , i64 %n) {
784ebe5b7SGraham Hunter; CHECK-LABEL: define void @test_uniform
884ebe5b7SGraham Hunter; CHECK-SAME: (ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i64 [[UNIFORM:%.*]], i64 [[N:%.*]]) {
984ebe5b7SGraham Hunter; CHECK-NEXT:  entry:
1084ebe5b7SGraham Hunter; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 2
1184ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1284ebe5b7SGraham Hunter; CHECK:       vector.ph:
1384ebe5b7SGraham Hunter; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -2
1484ebe5b7SGraham Hunter; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1584ebe5b7SGraham Hunter; CHECK:       vector.body:
1684ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1784ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr double, ptr [[SRC]], i64 [[INDEX]]
1884ebe5b7SGraham Hunter; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x double>, ptr [[TMP0]], align 8
19104b7c62SGraham Hunter; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x double> @foo_uniform(<2 x double> [[WIDE_LOAD]], i64 [[UNIFORM]])
20104b7c62SGraham Hunter; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 [[INDEX]]
21104b7c62SGraham Hunter; CHECK-NEXT:    store <2 x double> [[TMP1]], ptr [[TMP2]], align 8
2284ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
23104b7c62SGraham Hunter; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
24104b7c62SGraham Hunter; CHECK-NEXT:    br i1 [[TMP3]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
2584ebe5b7SGraham Hunter; CHECK:       middle.block:
26*a1058776SNikita Popov; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
2784ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]]
2884ebe5b7SGraham Hunter; CHECK:       scalar.ph:
2984ebe5b7SGraham Hunter; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
3084ebe5b7SGraham Hunter; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
3184ebe5b7SGraham Hunter; CHECK:       for.body:
3284ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
3384ebe5b7SGraham Hunter; CHECK-NEXT:    [[GEPSRC:%.*]] = getelementptr double, ptr [[SRC]], i64 [[INDVARS_IV]]
3484ebe5b7SGraham Hunter; CHECK-NEXT:    [[DATA:%.*]] = load double, ptr [[GEPSRC]], align 8
35104b7c62SGraham Hunter; CHECK-NEXT:    [[CALL:%.*]] = call double @foo(double [[DATA]], i64 [[UNIFORM]]) #[[ATTR0:[0-9]+]]
3684ebe5b7SGraham Hunter; CHECK-NEXT:    [[GEPDST:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 [[INDVARS_IV]]
3784ebe5b7SGraham Hunter; CHECK-NEXT:    store double [[CALL]], ptr [[GEPDST]], align 8
3884ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
3984ebe5b7SGraham Hunter; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
4084ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
4184ebe5b7SGraham Hunter; CHECK:       for.cond.cleanup:
4284ebe5b7SGraham Hunter; CHECK-NEXT:    ret void
4384ebe5b7SGraham Hunter;
4484ebe5b7SGraham Hunterentry:
4584ebe5b7SGraham Hunter  br label %for.body
4684ebe5b7SGraham Hunter
4784ebe5b7SGraham Hunterfor.body:
4884ebe5b7SGraham Hunter  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
4984ebe5b7SGraham Hunter  %gepsrc = getelementptr double, ptr %src, i64 %indvars.iv
5084ebe5b7SGraham Hunter  %data = load double, ptr %gepsrc, align 8
5184ebe5b7SGraham Hunter  %call = call double @foo(double %data, i64 %uniform) #0
5284ebe5b7SGraham Hunter  %gepdst = getelementptr inbounds double, ptr %dst, i64 %indvars.iv
5384ebe5b7SGraham Hunter  store double %call, ptr %gepdst
5484ebe5b7SGraham Hunter  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
5584ebe5b7SGraham Hunter  %exitcond = icmp eq i64 %indvars.iv.next, %n
5684ebe5b7SGraham Hunter  br i1 %exitcond, label %for.cond.cleanup, label %for.body
5784ebe5b7SGraham Hunter
5884ebe5b7SGraham Hunterfor.cond.cleanup:
5984ebe5b7SGraham Hunter  ret void
6084ebe5b7SGraham Hunter}
6184ebe5b7SGraham Hunter
6284ebe5b7SGraham Hunter; If the parameter is not uniform, then we can't use the vector variant and
6384ebe5b7SGraham Hunter; must fall back to scalarization.
6484ebe5b7SGraham Hunterdefine void @test_uniform_not_invariant(ptr noalias %dst, ptr readonly %src, i64 %n) {
6584ebe5b7SGraham Hunter; CHECK-LABEL: define void @test_uniform_not_invariant
6684ebe5b7SGraham Hunter; CHECK-SAME: (ptr noalias [[DST:%.*]], ptr readonly [[SRC:%.*]], i64 [[N:%.*]]) {
6784ebe5b7SGraham Hunter; CHECK-NEXT:  entry:
6884ebe5b7SGraham Hunter; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 2
6984ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
7084ebe5b7SGraham Hunter; CHECK:       vector.ph:
7184ebe5b7SGraham Hunter; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[N]], -2
7284ebe5b7SGraham Hunter; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
7384ebe5b7SGraham Hunter; CHECK:       vector.body:
7484ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
7503d4a9d9SCraig Topper; CHECK-NEXT:    [[TMP0:%.*]] = or disjoint i64 [[INDEX]], 1
7684ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr double, ptr [[SRC]], i64 [[INDEX]]
7784ebe5b7SGraham Hunter; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x double>, ptr [[TMP1]], align 8
7884ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x double> [[WIDE_LOAD]], i64 0
7984ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo(double [[TMP2]], i64 [[INDEX]]) #[[ATTR0]]
8084ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[WIDE_LOAD]], i64 1
8184ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP5:%.*]] = call double @foo(double [[TMP4]], i64 [[TMP0]]) #[[ATTR0]]
8284ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x double> poison, double [[TMP3]], i64 0
8384ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <2 x double> [[TMP6]], double [[TMP5]], i64 1
8484ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 [[INDEX]]
8584ebe5b7SGraham Hunter; CHECK-NEXT:    store <2 x double> [[TMP7]], ptr [[TMP8]], align 8
8684ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
8784ebe5b7SGraham Hunter; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
8884ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
8984ebe5b7SGraham Hunter; CHECK:       middle.block:
90*a1058776SNikita Popov; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
9184ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]]
9284ebe5b7SGraham Hunter; CHECK:       scalar.ph:
9384ebe5b7SGraham Hunter; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
9484ebe5b7SGraham Hunter; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
9584ebe5b7SGraham Hunter; CHECK:       for.body:
9684ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
9784ebe5b7SGraham Hunter; CHECK-NEXT:    [[GEPSRC:%.*]] = getelementptr double, ptr [[SRC]], i64 [[INDVARS_IV]]
9884ebe5b7SGraham Hunter; CHECK-NEXT:    [[DATA:%.*]] = load double, ptr [[GEPSRC]], align 8
9984ebe5b7SGraham Hunter; CHECK-NEXT:    [[CALL:%.*]] = call double @foo(double [[DATA]], i64 [[INDVARS_IV]]) #[[ATTR0]]
10084ebe5b7SGraham Hunter; CHECK-NEXT:    [[GEPDST:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 [[INDVARS_IV]]
10184ebe5b7SGraham Hunter; CHECK-NEXT:    store double [[CALL]], ptr [[GEPDST]], align 8
10284ebe5b7SGraham Hunter; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
10384ebe5b7SGraham Hunter; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[N]]
10484ebe5b7SGraham Hunter; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
10584ebe5b7SGraham Hunter; CHECK:       for.cond.cleanup:
10684ebe5b7SGraham Hunter; CHECK-NEXT:    ret void
10784ebe5b7SGraham Hunter;
10884ebe5b7SGraham Hunterentry:
10984ebe5b7SGraham Hunter  br label %for.body
11084ebe5b7SGraham Hunter
11184ebe5b7SGraham Hunterfor.body:
11284ebe5b7SGraham Hunter  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
11384ebe5b7SGraham Hunter  %gepsrc = getelementptr double, ptr %src, i64 %indvars.iv
11484ebe5b7SGraham Hunter  %data = load double, ptr %gepsrc, align 8
11584ebe5b7SGraham Hunter  %call = call double @foo(double %data, i64 %indvars.iv) #0
11684ebe5b7SGraham Hunter  %gepdst = getelementptr inbounds double, ptr %dst, i64 %indvars.iv
11784ebe5b7SGraham Hunter  store double %call, ptr %gepdst
11884ebe5b7SGraham Hunter  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
11984ebe5b7SGraham Hunter  %exitcond = icmp eq i64 %indvars.iv.next, %n
12084ebe5b7SGraham Hunter  br i1 %exitcond, label %for.cond.cleanup, label %for.body
12184ebe5b7SGraham Hunter
12284ebe5b7SGraham Hunterfor.cond.cleanup:
12384ebe5b7SGraham Hunter  ret void
12484ebe5b7SGraham Hunter}
12584ebe5b7SGraham Hunter
12684ebe5b7SGraham Hunter; Scalar functions
12784ebe5b7SGraham Hunterdeclare double @foo(double, i64)
12884ebe5b7SGraham Hunter
12984ebe5b7SGraham Hunter; Vector variants
13084ebe5b7SGraham Hunterdeclare <2 x double> @foo_uniform(<2 x double>, i64)
13184ebe5b7SGraham Hunter
13284ebe5b7SGraham Hunter; Mappings
13384ebe5b7SGraham Hunterattributes #0 = { nounwind "vector-function-abi-variant"="_ZGV_LLVM_N2vu_foo(foo_uniform)" }
134