| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt < %s -passes=loop-vectorize -mtriple sparc -S | FileCheck %s -check-prefixes=SPARC,SPARC32 |
| ; RUN: opt < %s -passes=loop-vectorize -mtriple sparcv9 -S | FileCheck %s -check-prefixes=SPARC,SPARC64 |
| |
| ;; At the moment the backend doesn't support vector instructions. |
| ;; Make sure that nothing gets vectorized, even those with explicit hints. |
| ;; The code is based on the C++ reproducer at https://github.com/sparclinux/issues/issues/69#issuecomment-3822053617 |
| |
| @glob = global i16 0, align 2 |
| |
| define fastcc void @novectorize(ptr %__args1, i16 %__args3) { |
| ; SPARC-LABEL: define fastcc void @novectorize( |
| ; SPARC-SAME: ptr [[__ARGS1:%.*]], i16 [[__ARGS3:%.*]]) { |
| ; SPARC-NEXT: [[ENTRY:.*:]] |
| ; SPARC-NEXT: [[TOBOOL_NOT2_I_I:%.*]] = icmp eq i16 [[__ARGS3]], 0 |
| ; SPARC-NEXT: br i1 [[TOBOOL_NOT2_I_I]], label %[[EXIT:.*]], label %[[FOR_BODY_PREHEADER_I_I:.*]] |
| ; SPARC: [[FOR_BODY_PREHEADER_I_I]]: |
| ; SPARC-NEXT: [[GLOB_PROMOTED_I_I:%.*]] = load i16, ptr @glob, align 2 |
| ; SPARC-NEXT: br label %[[FOR_BODY_I_I:.*]] |
| ; SPARC: [[FOR_BODY_I_I]]: |
| ; SPARC-NEXT: [[I_04_I_I:%.*]] = phi i16 [ [[SUB_I_I:%.*]], %[[FOR_BODY_I_I]] ], [ [[__ARGS3]], %[[FOR_BODY_PREHEADER_I_I]] ] |
| ; SPARC-NEXT: [[COND13_I_I:%.*]] = phi i16 [ [[COND_I_I:%.*]], %[[FOR_BODY_I_I]] ], [ [[GLOB_PROMOTED_I_I]], %[[FOR_BODY_PREHEADER_I_I]] ] |
| ; SPARC-NEXT: [[IDXPROM_I_I:%.*]] = sext i16 [[I_04_I_I]] to i32 |
| ; SPARC-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds i16, ptr [[__ARGS1]], i32 [[IDXPROM_I_I]] |
| ; SPARC-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX_I_I]], align 2 |
| ; SPARC-NEXT: [[TOBOOL2_NOT_I_I:%.*]] = icmp eq i16 [[TMP0]], 0 |
| ; SPARC-NEXT: [[COND_I_I]] = select i1 [[TOBOOL2_NOT_I_I]], i16 [[COND13_I_I]], i16 [[TMP0]] |
| ; SPARC-NEXT: store i16 [[COND_I_I]], ptr @glob, align 2 |
| ; SPARC-NEXT: [[SUB_I_I]] = add i16 [[I_04_I_I]], -1 |
| ; SPARC-NEXT: [[TOBOOL_NOT_I_I:%.*]] = icmp eq i16 [[SUB_I_I]], 0 |
| ; SPARC-NEXT: br i1 [[TOBOOL_NOT_I_I]], label %[[EXIT]], label %[[FOR_BODY_I_I]], !llvm.loop [[LOOP0:![0-9]+]] |
| ; SPARC: [[EXIT]]: |
| ; SPARC-NEXT: ret void |
| ; |
| entry: |
| %tobool.not2.i.i = icmp eq i16 %__args3, 0 |
| br i1 %tobool.not2.i.i, label %exit, label %for.body.preheader.i.i |
| |
| for.body.preheader.i.i: |
| %glob.promoted.i.i = load i16, ptr @glob, align 2 |
| br label %for.body.i.i |
| |
| for.body.i.i: |
| %I.04.i.i = phi i16 [ %sub.i.i, %for.body.i.i ], [ %__args3, %for.body.preheader.i.i ] |
| %cond13.i.i = phi i16 [ %cond.i.i, %for.body.i.i ], [ %glob.promoted.i.i, %for.body.preheader.i.i ] |
| %idxprom.i.i = sext i16 %I.04.i.i to i32 |
| %arrayidx.i.i = getelementptr inbounds i16, ptr %__args1, i32 %idxprom.i.i |
| %0 = load i16, ptr %arrayidx.i.i, align 2 |
| %tobool2.not.i.i = icmp eq i16 %0, 0 |
| %cond.i.i = select i1 %tobool2.not.i.i, i16 %cond13.i.i, i16 %0 |
| store i16 %cond.i.i, ptr @glob, align 2 |
| %sub.i.i = add i16 %I.04.i.i, -1 |
| %tobool.not.i.i = icmp eq i16 %sub.i.i, 0 |
| br i1 %tobool.not.i.i, label %exit, label %for.body.i.i, !llvm.loop !1 |
| |
| exit: |
| ret void |
| } |
| |
| !1 = distinct !{!1, !2, !3} |
| !2 = !{!"llvm.loop.mustprogress"} |
| !3 = !{!"llvm.loop.vectorize.enable", i1 true} |
| ;. |
| ; SPARC32: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]} |
| ; SPARC32: [[META1]] = !{!"llvm.loop.mustprogress"} |
| ; SPARC32: [[META2]] = !{!"llvm.loop.vectorize.enable", i1 true} |
| ;. |
| ; SPARC64: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]} |
| ; SPARC64: [[META1]] = !{!"llvm.loop.mustprogress"} |
| ; SPARC64: [[META2]] = !{!"llvm.loop.vectorize.enable", i1 true} |
| ;. |
| ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: |
| ; SPARC32: {{.*}} |
| ; SPARC64: {{.*}} |