Skip to content

Commit e0f00bd

Browse files
committed
[LV] Don't consider second op as invariant in getDivRemSpeculationCost.
The second operand when using a safe divisor will always be a select in the loop, so won't be invariant; don't treat it as such. This fixes a divergence with legacy and VPlan based cost model. Fixes llvm/llvm-project#156066.
1 parent 667f919 commit e0f00bd

File tree

2 files changed

+144
-11
lines changed

2 files changed

+144
-11
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2910,19 +2910,12 @@ LoopVectorizationCostModel::getDivRemSpeculationCost(Instruction *I,
29102910
toVectorTy(Type::getInt1Ty(I->getContext()), VF),
29112911
CmpInst::BAD_ICMP_PREDICATE, CostKind);
29122912

2913-
// Certain instructions can be cheaper to vectorize if they have a constant
2914-
// second vector operand. One example of this are shifts on x86.
2915-
Value *Op2 = I->getOperand(1);
2916-
auto Op2Info = TTI.getOperandInfo(Op2);
2917-
if (Op2Info.Kind == TargetTransformInfo::OK_AnyValue &&
2918-
Legal->isInvariant(Op2))
2919-
Op2Info.Kind = TargetTransformInfo::OK_UniformValue;
2920-
29212913
SmallVector<const Value *, 4> Operands(I->operand_values());
29222914
SafeDivisorCost += TTI.getArithmeticInstrCost(
2923-
I->getOpcode(), VecTy, CostKind,
2924-
{TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
2925-
Op2Info, Operands, I);
2915+
I->getOpcode(), VecTy, CostKind,
2916+
{TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
2917+
{TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None},
2918+
Operands, I);
29262919
return {ScalarizationCost, SafeDivisorCost};
29272920
}
29282921

llvm/test/Transforms/LoopVectorize/X86/cost-conditional-branches.ll

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,146 @@ exit:
752752
ret i32 %p.2
753753
}
754754

755+
; Test case for https://github.com/llvm/llvm-project/issues/156066.
756+
define void @sdiv_by_zero(ptr noalias %src, ptr noalias %dst, i32 %d) #2 {
757+
; CHECK-LABEL: @sdiv_by_zero(
758+
; CHECK-NEXT: bb:
759+
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
760+
; CHECK: vector.ph:
761+
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
762+
; CHECK: vector.body:
763+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_SDIV_CONTINUE14:%.*]] ]
764+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[INDEX]]
765+
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <8 x i32>, ptr [[TMP0]], align 4
766+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <8 x i32> [[WIDE_LOAD]], zeroinitializer
767+
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x i1> [[TMP1]], i32 0
768+
; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_SDIV_IF:%.*]], label [[PRED_SDIV_CONTINUE:%.*]]
769+
; CHECK: pred.sdiv.if:
770+
; CHECK-NEXT: [[TMP3:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 0
771+
; CHECK-NEXT: [[TMP4:%.*]] = sdiv i32 [[TMP3]], 0
772+
; CHECK-NEXT: [[TMP5:%.*]] = insertelement <8 x i32> poison, i32 [[TMP4]], i32 0
773+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE]]
774+
; CHECK: pred.sdiv.continue:
775+
; CHECK-NEXT: [[TMP6:%.*]] = phi <8 x i32> [ poison, [[VECTOR_BODY]] ], [ [[TMP5]], [[PRED_SDIV_IF]] ]
776+
; CHECK-NEXT: [[TMP7:%.*]] = extractelement <8 x i1> [[TMP1]], i32 1
777+
; CHECK-NEXT: br i1 [[TMP7]], label [[PRED_SDIV_IF1:%.*]], label [[PRED_SDIV_CONTINUE2:%.*]]
778+
; CHECK: pred.sdiv.if1:
779+
; CHECK-NEXT: [[TMP8:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 1
780+
; CHECK-NEXT: [[TMP9:%.*]] = sdiv i32 [[TMP8]], 0
781+
; CHECK-NEXT: [[TMP10:%.*]] = insertelement <8 x i32> [[TMP6]], i32 [[TMP9]], i32 1
782+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE2]]
783+
; CHECK: pred.sdiv.continue2:
784+
; CHECK-NEXT: [[TMP11:%.*]] = phi <8 x i32> [ [[TMP6]], [[PRED_SDIV_CONTINUE]] ], [ [[TMP10]], [[PRED_SDIV_IF1]] ]
785+
; CHECK-NEXT: [[TMP12:%.*]] = extractelement <8 x i1> [[TMP1]], i32 2
786+
; CHECK-NEXT: br i1 [[TMP12]], label [[PRED_SDIV_IF3:%.*]], label [[PRED_SDIV_CONTINUE4:%.*]]
787+
; CHECK: pred.sdiv.if3:
788+
; CHECK-NEXT: [[TMP13:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 2
789+
; CHECK-NEXT: [[TMP14:%.*]] = sdiv i32 [[TMP13]], 0
790+
; CHECK-NEXT: [[TMP15:%.*]] = insertelement <8 x i32> [[TMP11]], i32 [[TMP14]], i32 2
791+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE4]]
792+
; CHECK: pred.sdiv.continue4:
793+
; CHECK-NEXT: [[TMP16:%.*]] = phi <8 x i32> [ [[TMP11]], [[PRED_SDIV_CONTINUE2]] ], [ [[TMP15]], [[PRED_SDIV_IF3]] ]
794+
; CHECK-NEXT: [[TMP17:%.*]] = extractelement <8 x i1> [[TMP1]], i32 3
795+
; CHECK-NEXT: br i1 [[TMP17]], label [[PRED_SDIV_IF5:%.*]], label [[PRED_SDIV_CONTINUE6:%.*]]
796+
; CHECK: pred.sdiv.if5:
797+
; CHECK-NEXT: [[TMP18:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 3
798+
; CHECK-NEXT: [[TMP19:%.*]] = sdiv i32 [[TMP18]], 0
799+
; CHECK-NEXT: [[TMP20:%.*]] = insertelement <8 x i32> [[TMP16]], i32 [[TMP19]], i32 3
800+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE6]]
801+
; CHECK: pred.sdiv.continue6:
802+
; CHECK-NEXT: [[TMP21:%.*]] = phi <8 x i32> [ [[TMP16]], [[PRED_SDIV_CONTINUE4]] ], [ [[TMP20]], [[PRED_SDIV_IF5]] ]
803+
; CHECK-NEXT: [[TMP22:%.*]] = extractelement <8 x i1> [[TMP1]], i32 4
804+
; CHECK-NEXT: br i1 [[TMP22]], label [[PRED_SDIV_IF7:%.*]], label [[PRED_SDIV_CONTINUE8:%.*]]
805+
; CHECK: pred.sdiv.if7:
806+
; CHECK-NEXT: [[TMP23:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 4
807+
; CHECK-NEXT: [[TMP24:%.*]] = sdiv i32 [[TMP23]], 0
808+
; CHECK-NEXT: [[TMP25:%.*]] = insertelement <8 x i32> [[TMP21]], i32 [[TMP24]], i32 4
809+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE8]]
810+
; CHECK: pred.sdiv.continue8:
811+
; CHECK-NEXT: [[TMP26:%.*]] = phi <8 x i32> [ [[TMP21]], [[PRED_SDIV_CONTINUE6]] ], [ [[TMP25]], [[PRED_SDIV_IF7]] ]
812+
; CHECK-NEXT: [[TMP27:%.*]] = extractelement <8 x i1> [[TMP1]], i32 5
813+
; CHECK-NEXT: br i1 [[TMP27]], label [[PRED_SDIV_IF9:%.*]], label [[PRED_SDIV_CONTINUE10:%.*]]
814+
; CHECK: pred.sdiv.if9:
815+
; CHECK-NEXT: [[TMP28:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 5
816+
; CHECK-NEXT: [[TMP29:%.*]] = sdiv i32 [[TMP28]], 0
817+
; CHECK-NEXT: [[TMP30:%.*]] = insertelement <8 x i32> [[TMP26]], i32 [[TMP29]], i32 5
818+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE10]]
819+
; CHECK: pred.sdiv.continue10:
820+
; CHECK-NEXT: [[TMP31:%.*]] = phi <8 x i32> [ [[TMP26]], [[PRED_SDIV_CONTINUE8]] ], [ [[TMP30]], [[PRED_SDIV_IF9]] ]
821+
; CHECK-NEXT: [[TMP32:%.*]] = extractelement <8 x i1> [[TMP1]], i32 6
822+
; CHECK-NEXT: br i1 [[TMP32]], label [[PRED_SDIV_IF11:%.*]], label [[PRED_SDIV_CONTINUE12:%.*]]
823+
; CHECK: pred.sdiv.if11:
824+
; CHECK-NEXT: [[TMP33:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 6
825+
; CHECK-NEXT: [[TMP34:%.*]] = sdiv i32 [[TMP33]], 0
826+
; CHECK-NEXT: [[TMP35:%.*]] = insertelement <8 x i32> [[TMP31]], i32 [[TMP34]], i32 6
827+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE12]]
828+
; CHECK: pred.sdiv.continue12:
829+
; CHECK-NEXT: [[TMP36:%.*]] = phi <8 x i32> [ [[TMP31]], [[PRED_SDIV_CONTINUE10]] ], [ [[TMP35]], [[PRED_SDIV_IF11]] ]
830+
; CHECK-NEXT: [[TMP37:%.*]] = extractelement <8 x i1> [[TMP1]], i32 7
831+
; CHECK-NEXT: br i1 [[TMP37]], label [[PRED_SDIV_IF13:%.*]], label [[PRED_SDIV_CONTINUE14]]
832+
; CHECK: pred.sdiv.if13:
833+
; CHECK-NEXT: [[TMP38:%.*]] = extractelement <8 x i32> [[WIDE_LOAD]], i32 7
834+
; CHECK-NEXT: [[TMP39:%.*]] = sdiv i32 [[TMP38]], 0
835+
; CHECK-NEXT: [[TMP40:%.*]] = insertelement <8 x i32> [[TMP36]], i32 [[TMP39]], i32 7
836+
; CHECK-NEXT: br label [[PRED_SDIV_CONTINUE14]]
837+
; CHECK: pred.sdiv.continue14:
838+
; CHECK-NEXT: [[TMP41:%.*]] = phi <8 x i32> [ [[TMP36]], [[PRED_SDIV_CONTINUE12]] ], [ [[TMP40]], [[PRED_SDIV_IF13]] ]
839+
; CHECK-NEXT: [[PREDPHI:%.*]] = select <8 x i1> [[TMP1]], <8 x i32> [[TMP41]], <8 x i32> zeroinitializer
840+
; CHECK-NEXT: [[TMP42:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[INDEX]]
841+
; CHECK-NEXT: store <8 x i32> [[PREDPHI]], ptr [[TMP42]], align 4
842+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
843+
; CHECK-NEXT: [[TMP43:%.*]] = icmp eq i64 [[INDEX_NEXT]], 16
844+
; CHECK-NEXT: br i1 [[TMP43]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
845+
; CHECK: middle.block:
846+
; CHECK-NEXT: br label [[SCALAR_PH]]
847+
; CHECK: scalar.ph:
848+
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 16, [[MIDDLE_BLOCK]] ], [ 0, [[BB:%.*]] ]
849+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
850+
; CHECK: loop.header:
851+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
852+
; CHECK-NEXT: [[GEP_SRC:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i64 [[IV]]
853+
; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 4
854+
; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[L]], 0
855+
; CHECK-NEXT: br i1 [[ICMP]], label [[LOOP_LATCH]], label [[THEN:%.*]]
856+
; CHECK: then:
857+
; CHECK-NEXT: [[SDIV:%.*]] = sdiv i32 [[L]], 0
858+
; CHECK-NEXT: br label [[LOOP_LATCH]]
859+
; CHECK: loop.latch:
860+
; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[SDIV]], [[THEN]] ], [ 0, [[LOOP_HEADER]] ]
861+
; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
862+
; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_DST]], align 4
863+
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
864+
; CHECK-NEXT: [[EC:%.*]] = icmp ult i64 [[IV]], 16
865+
; CHECK-NEXT: br i1 [[EC]], label [[LOOP_HEADER]], label [[EXIT:%.*]], !llvm.loop [[LOOP11:![0-9]+]]
866+
; CHECK: exit:
867+
; CHECK-NEXT: ret void
868+
;
869+
bb:
870+
br label %loop.header
871+
872+
loop.header:
873+
%iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %bb ]
874+
%gep.src = getelementptr inbounds i32, ptr %src, i64 %iv
875+
%l = load i32, ptr %gep.src, align 4
876+
%icmp = icmp eq i32 %l, 0
877+
br i1 %icmp, label %loop.latch, label %then
878+
879+
then:
880+
%sdiv = sdiv i32 %l, 0
881+
br label %loop.latch
882+
883+
loop.latch:
884+
%merge = phi i32 [ %sdiv, %then ], [ 0, %loop.header ]
885+
%gep.dst = getelementptr inbounds i32, ptr %dst, i64 %iv
886+
store i32 %merge, ptr %gep.dst, align 4
887+
%iv.next = add i64 %iv, 1
888+
%ec = icmp ult i64 %iv, 16
889+
br i1 %ec, label %loop.header, label %exit
890+
891+
exit:
892+
ret void
893+
}
894+
755895
attributes #0 = { "target-cpu"="znver4" }
756896
attributes #1 = { "target-features"="+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl" }
757897
attributes #2 = { "target-cpu"="znver3" }

0 commit comments

Comments
 (0)