[PhaseOrdering] Add test for vectorization requiring hoisting/sinking.
authorFlorian Hahn <flo@fhahn.com>
Wed, 28 Apr 2021 15:36:30 +0000 (16:36 +0100)
committerFlorian Hahn <flo@fhahn.com>
Wed, 28 Apr 2021 16:05:27 +0000 (17:05 +0100)
llvm/test/Transforms/PhaseOrdering/AArch64/hoisting-sinking-required-for-vectorization.ll [moved from llvm/test/Transforms/PhaseOrdering/AArch64/hoisting-required-for-vectorization.ll with 72% similarity]

@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes='default<O3>' -S < %s  | FileCheck %s
+; RUN: opt -passes='default<O3>' -S %s | FileCheck %s
 
 target triple = "arm64-apple-darwin"
 
@@ -135,6 +135,75 @@ for.end:                                          ; preds = %for.cond.cleanup
   ret void
 }
 
+; Test that requires sinking/hoisting of instructions for vectorization.
+
+define void @loop2(float* %A, float* %B, i32* %C, float %x) {
+; CHECK-LABEL: @loop2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP_BODY:%.*]]
+; CHECK:       loop.body:
+; CHECK-NEXT:    [[IV1:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[C_GEP:%.*]] = getelementptr inbounds i32, i32* [[C:%.*]], i64 [[IV1]]
+; CHECK-NEXT:    [[C_LV:%.*]] = load i32, i32* [[C_GEP]], align 4
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[C_LV]], 20
+; CHECK-NEXT:    [[A_GEP_0:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 [[IV1]]
+; CHECK-NEXT:    [[A_LV_0:%.*]] = load float, float* [[A_GEP_0]], align 4
+; CHECK-NEXT:    [[MUL2_I81_I:%.*]] = fmul float [[A_LV_0]], [[X:%.*]]
+; CHECK-NEXT:    [[B_GEP_0:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 [[IV1]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP_LATCH]], label [[ELSE:%.*]]
+; CHECK:       else:
+; CHECK-NEXT:    [[B_LV:%.*]] = load float, float* [[B_GEP_0]], align 4
+; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[MUL2_I81_I]], [[B_LV]]
+; CHECK-NEXT:    br label [[LOOP_LATCH]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[ADD_SINK:%.*]] = phi float [ [[ADD]], [[ELSE]] ], [ [[MUL2_I81_I]], [[LOOP_BODY]] ]
+; CHECK-NEXT:    store float [[ADD_SINK]], float* [[B_GEP_0]], align 4
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV1]], 1
+; CHECK-NEXT:    [[CMP_0:%.*]] = icmp ult i64 [[IV1]], 9999
+; CHECK-NEXT:    br i1 [[CMP_0]], label [[LOOP_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop.header
+
+loop.header:
+  %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %entry ]
+  %cmp.0 = icmp ult i64 %iv, 10000
+  br i1 %cmp.0, label %loop.body, label %exit
+
+loop.body:
+  %C.gep = getelementptr inbounds i32, i32* %C, i64 %iv
+  %C.lv = load i32, i32* %C.gep
+  %cmp = icmp eq i32 %C.lv, 20
+  br i1 %cmp, label %then, label %else
+
+then:
+  %A.gep.0 = getelementptr inbounds float, float* %A, i64 %iv
+  %A.lv.0 = load float, float* %A.gep.0, align 4
+  %mul2.i81.i = fmul float %A.lv.0, %x
+  %B.gep.0 = getelementptr inbounds float, float* %B, i64 %iv
+  store float %mul2.i81.i, float* %B.gep.0, align 4
+  br label %loop.latch
+
+else:
+  %A.gep.1 = getelementptr inbounds float, float* %A, i64 %iv
+  %A.lv.1 = load float, float* %A.gep.1, align 4
+  %mul2 = fmul float %A.lv.1, %x
+  %B.gep.1 = getelementptr inbounds float, float* %B, i64 %iv
+  %B.lv = load float, float* %B.gep.1, align 4
+  %add = fadd float %mul2, %B.lv
+  store float %add, float* %B.gep.1, align 4
+  br label %loop.latch
+
+loop.latch:
+  %iv.next = add nuw nsw i64 %iv, 1
+  br label %loop.header
+
+exit:
+  ret void
+}
+
 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
 
 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)