forked from OSchip/llvm-project
[ARM] Test for predicated scalar memops. NFC
This test shows a case where we can potentially scalarize the store in a predicated loop, creating a lot of instructions that would be much slower than scalar.
This commit is contained in:
parent
82400ae016
commit
fa450e98c5
|
@ -0,0 +1,139 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -loop-vectorize < %s -S -o - | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
|
||||
target triple = "thumbv8.1m.main-arm-none-eabi"
|
||||
|
||||
; This test could produce gather/scatter or predicated scalar load/stores. It
|
||||
; should never choose scalar load/store, and the cost of gather/scatter may be
|
||||
; high enough to make vectorization unwarranted.
|
||||
|
||||
define i32 @nested(float* nocapture %pG, float* nocapture readonly %pA, i32 %n, i32 %ii) #0 {
|
||||
; CHECK-LABEL: @nested(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CMP66:%.*]] = icmp sgt i32 [[N:%.*]], 0
|
||||
; CHECK-NEXT: br i1 [[CMP66]], label [[FOR_BODY4_LR_PH_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
||||
; CHECK: for.body4.lr.ph.preheader:
|
||||
; CHECK-NEXT: br label [[FOR_BODY4_LR_PH:%.*]]
|
||||
; CHECK: for.body4.lr.ph:
|
||||
; CHECK-NEXT: [[I_067:%.*]] = phi i32 [ [[INC29:%.*]], [[FOR_COND_CLEANUP3:%.*]] ], [ 0, [[FOR_BODY4_LR_PH_PREHEADER]] ]
|
||||
; CHECK-NEXT: [[CMP962_NOT:%.*]] = icmp eq i32 [[I_067]], 0
|
||||
; CHECK-NEXT: [[MUL15:%.*]] = mul nsw i32 [[I_067]], [[N]]
|
||||
; CHECK-NEXT: br i1 [[CMP962_NOT]], label [[FOR_BODY4_PREHEADER:%.*]], label [[FOR_BODY4_US_PREHEADER:%.*]]
|
||||
; CHECK: for.body4.us.preheader:
|
||||
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
|
||||
; CHECK: for.body4.preheader:
|
||||
; CHECK-NEXT: br label [[FOR_BODY4:%.*]]
|
||||
; CHECK: for.body4.us:
|
||||
; CHECK-NEXT: [[J_065_US:%.*]] = phi i32 [ [[INC26_US:%.*]], [[FOR_COND8_FOR_COND_CLEANUP10_CRIT_EDGE_US:%.*]] ], [ [[I_067]], [[FOR_BODY4_US_PREHEADER]] ]
|
||||
; CHECK-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[J_065_US]], [[N]]
|
||||
; CHECK-NEXT: [[ADD_US:%.*]] = add nsw i32 [[MUL_US]], [[I_067]]
|
||||
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds float, float* [[PA:%.*]], i32 [[ADD_US]]
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[ARRAYIDX_US]], align 4
|
||||
; CHECK-NEXT: [[ARRAYIDX7_US:%.*]] = getelementptr inbounds float, float* [[PG:%.*]], i32 [[ADD_US]]
|
||||
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX7_US]], align 4
|
||||
; CHECK-NEXT: br label [[FOR_BODY11_US:%.*]]
|
||||
; CHECK: for.body11.us:
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = phi float [ [[TMP0]], [[FOR_BODY4_US]] ], [ [[SUB_US:%.*]], [[FOR_BODY11_US]] ]
|
||||
; CHECK-NEXT: [[K_063_US:%.*]] = phi i32 [ 0, [[FOR_BODY4_US]] ], [ [[INC_US:%.*]], [[FOR_BODY11_US]] ]
|
||||
; CHECK-NEXT: [[ADD16_US:%.*]] = add nsw i32 [[K_063_US]], [[MUL15]]
|
||||
; CHECK-NEXT: [[ARRAYIDX17_US:%.*]] = getelementptr inbounds float, float* [[PG]], i32 [[ADD16_US]]
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[ARRAYIDX17_US]], align 4
|
||||
; CHECK-NEXT: [[ADD19_US:%.*]] = add nsw i32 [[K_063_US]], [[MUL_US]]
|
||||
; CHECK-NEXT: [[ARRAYIDX20_US:%.*]] = getelementptr inbounds float, float* [[PG]], i32 [[ADD19_US]]
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = load float, float* [[ARRAYIDX20_US]], align 4
|
||||
; CHECK-NEXT: [[MUL21_US:%.*]] = fmul fast float [[TMP3]], [[TMP2]]
|
||||
; CHECK-NEXT: [[SUB_US]] = fsub fast float [[TMP1]], [[MUL21_US]]
|
||||
; CHECK-NEXT: store float [[SUB_US]], float* [[ARRAYIDX7_US]], align 4
|
||||
; CHECK-NEXT: [[INC_US]] = add nuw nsw i32 [[K_063_US]], 1
|
||||
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC_US]], [[I_067]]
|
||||
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND8_FOR_COND_CLEANUP10_CRIT_EDGE_US]], label [[FOR_BODY11_US]]
|
||||
; CHECK: for.cond8.for.cond.cleanup10_crit_edge.us:
|
||||
; CHECK-NEXT: [[INC26_US]] = add nuw nsw i32 [[J_065_US]], 1
|
||||
; CHECK-NEXT: [[EXITCOND71_NOT:%.*]] = icmp eq i32 [[INC26_US]], [[N]]
|
||||
; CHECK-NEXT: br i1 [[EXITCOND71_NOT]], label [[FOR_COND_CLEANUP3_LOOPEXIT1:%.*]], label [[FOR_BODY4_US]]
|
||||
; CHECK: for.cond.cleanup.loopexit:
|
||||
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
|
||||
; CHECK: for.cond.cleanup:
|
||||
; CHECK-NEXT: ret i32 0
|
||||
; CHECK: for.cond.cleanup3.loopexit:
|
||||
; CHECK-NEXT: br label [[FOR_COND_CLEANUP3]]
|
||||
; CHECK: for.cond.cleanup3.loopexit1:
|
||||
; CHECK-NEXT: br label [[FOR_COND_CLEANUP3]]
|
||||
; CHECK: for.cond.cleanup3:
|
||||
; CHECK-NEXT: [[INC29]] = add nuw nsw i32 [[I_067]], 1
|
||||
; CHECK-NEXT: [[EXITCOND73_NOT:%.*]] = icmp eq i32 [[INC29]], [[N]]
|
||||
; CHECK-NEXT: br i1 [[EXITCOND73_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[FOR_BODY4_LR_PH]]
|
||||
; CHECK: for.body4:
|
||||
; CHECK-NEXT: [[J_065:%.*]] = phi i32 [ [[INC26:%.*]], [[FOR_BODY4]] ], [ 0, [[FOR_BODY4_PREHEADER]] ]
|
||||
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[J_065]], [[N]]
|
||||
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[PA]], i32 [[MUL]]
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load float, float* [[ARRAYIDX]], align 4
|
||||
; CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds float, float* [[PG]], i32 [[MUL]]
|
||||
; CHECK-NEXT: store float [[TMP4]], float* [[ARRAYIDX7]], align 4
|
||||
; CHECK-NEXT: [[INC26]] = add nuw nsw i32 [[J_065]], 1
|
||||
; CHECK-NEXT: [[EXITCOND72_NOT:%.*]] = icmp eq i32 [[INC26]], [[N]]
|
||||
; CHECK-NEXT: br i1 [[EXITCOND72_NOT]], label [[FOR_COND_CLEANUP3_LOOPEXIT:%.*]], label [[FOR_BODY4]]
|
||||
;
|
||||
entry:
|
||||
%cmp66 = icmp sgt i32 %n, 0
|
||||
br i1 %cmp66, label %for.body4.lr.ph, label %for.cond.cleanup
|
||||
|
||||
for.body4.lr.ph: ; preds = %entry, %for.cond.cleanup3
|
||||
%i.067 = phi i32 [ %inc29, %for.cond.cleanup3 ], [ 0, %entry ]
|
||||
%cmp962.not = icmp eq i32 %i.067, 0
|
||||
%mul15 = mul nsw i32 %i.067, %n
|
||||
br i1 %cmp962.not, label %for.body4, label %for.body4.us
|
||||
|
||||
for.body4.us: ; preds = %for.body4.lr.ph, %for.cond8.for.cond.cleanup10_crit_edge.us
|
||||
%j.065.us = phi i32 [ %inc26.us, %for.cond8.for.cond.cleanup10_crit_edge.us ], [ %i.067, %for.body4.lr.ph ]
|
||||
%mul.us = mul nsw i32 %j.065.us, %n
|
||||
%add.us = add nsw i32 %mul.us, %i.067
|
||||
%arrayidx.us = getelementptr inbounds float, float* %pA, i32 %add.us
|
||||
%0 = load float, float* %arrayidx.us, align 4
|
||||
%arrayidx7.us = getelementptr inbounds float, float* %pG, i32 %add.us
|
||||
store float %0, float* %arrayidx7.us, align 4
|
||||
br label %for.body11.us
|
||||
|
||||
for.body11.us: ; preds = %for.body4.us, %for.body11.us
|
||||
%1 = phi float [ %0, %for.body4.us ], [ %sub.us, %for.body11.us ]
|
||||
%k.063.us = phi i32 [ 0, %for.body4.us ], [ %inc.us, %for.body11.us ]
|
||||
%add16.us = add nsw i32 %k.063.us, %mul15
|
||||
%arrayidx17.us = getelementptr inbounds float, float* %pG, i32 %add16.us
|
||||
%2 = load float, float* %arrayidx17.us, align 4
|
||||
%add19.us = add nsw i32 %k.063.us, %mul.us
|
||||
%arrayidx20.us = getelementptr inbounds float, float* %pG, i32 %add19.us
|
||||
%3 = load float, float* %arrayidx20.us, align 4
|
||||
%mul21.us = fmul fast float %3, %2
|
||||
%sub.us = fsub fast float %1, %mul21.us
|
||||
store float %sub.us, float* %arrayidx7.us, align 4
|
||||
%inc.us = add nuw nsw i32 %k.063.us, 1
|
||||
%exitcond.not = icmp eq i32 %inc.us, %i.067
|
||||
br i1 %exitcond.not, label %for.cond8.for.cond.cleanup10_crit_edge.us, label %for.body11.us
|
||||
|
||||
for.cond8.for.cond.cleanup10_crit_edge.us: ; preds = %for.body11.us
|
||||
%inc26.us = add nuw nsw i32 %j.065.us, 1
|
||||
%exitcond71.not = icmp eq i32 %inc26.us, %n
|
||||
br i1 %exitcond71.not, label %for.cond.cleanup3, label %for.body4.us
|
||||
|
||||
for.cond.cleanup: ; preds = %for.cond.cleanup3, %entry
|
||||
ret i32 0
|
||||
|
||||
for.cond.cleanup3: ; preds = %for.cond8.for.cond.cleanup10_crit_edge.us, %for.body4
|
||||
%inc29 = add nuw nsw i32 %i.067, 1
|
||||
%exitcond73.not = icmp eq i32 %inc29, %n
|
||||
br i1 %exitcond73.not, label %for.cond.cleanup, label %for.body4.lr.ph
|
||||
|
||||
for.body4: ; preds = %for.body4.lr.ph, %for.body4
|
||||
%j.065 = phi i32 [ %inc26, %for.body4 ], [ 0, %for.body4.lr.ph ]
|
||||
%mul = mul nsw i32 %j.065, %n
|
||||
%arrayidx = getelementptr inbounds float, float* %pA, i32 %mul
|
||||
%4 = load float, float* %arrayidx, align 4
|
||||
%arrayidx7 = getelementptr inbounds float, float* %pG, i32 %mul
|
||||
store float %4, float* %arrayidx7, align 4
|
||||
%inc26 = add nuw nsw i32 %j.065, 1
|
||||
%exitcond72.not = icmp eq i32 %inc26, %n
|
||||
br i1 %exitcond72.not, label %for.cond.cleanup3, label %for.body4
|
||||
}
|
||||
|
||||
attributes #0 = { "target-features"="+mve" }
|
Loading…
Reference in New Issue