diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -1053,6 +1053,8 @@ // Check that the next levels binary operation exists and matches with the // current one. if (Level + 1 != NumLevels) { + if (!isa(NextLevelOp)) + return TTI::RK_None; Optional NextLevelRD = getReductionData(cast(NextLevelOp)); if (!NextLevelRD || !RD->hasSameData(*NextLevelRD)) @@ -1074,7 +1076,7 @@ return RD->Kind; // Match next level. - return matchPairwiseReductionAtLevel(cast(NextLevelOp), Level, + return matchPairwiseReductionAtLevel(dyn_cast(NextLevelOp), Level, NumLevels); } diff --git a/llvm/test/Transforms/LoopUnroll/X86/pr46430.ll b/llvm/test/Transforms/LoopUnroll/X86/pr46430.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopUnroll/X86/pr46430.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -mtriple=x86_64-unknown-linux-gnu -loop-unroll -costmodel-reduxcost -S -o - %s | FileCheck %s + +define void @g() { +; CHECK-LABEL: @g( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[F_EXIT:%.*]] +; CHECK: f.exit: +; CHECK-NEXT: [[RDX_SHUF9_I:%.*]] = shufflevector <4 x i16> , <4 x i16> undef, <4 x i32> +; CHECK-NEXT: [[BIN_RDX10_I:%.*]] = xor <4 x i16> , [[RDX_SHUF9_I]] +; CHECK-NEXT: [[TMP0:%.*]] = extractelement <4 x i16> [[BIN_RDX10_I]], i32 0 +; CHECK-NEXT: br label [[F_EXIT]] +; +entry: + br label %f.exit + +f.exit: ; preds = %f.exit, %entry + %rdx.shuf9.i = shufflevector <4 x i16> , <4 x i16> undef, <4 x i32> + %bin.rdx10.i = xor <4 x i16> , %rdx.shuf9.i + %0 = extractelement <4 x i16> %bin.rdx10.i, i32 0 + br label %f.exit +} +