From 23817cbd0b6549d6145e4d0dbc0162370184a21e Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 9 Aug 2020 16:48:44 +0100 Subject: [PATCH] [SCEVExpander] Make sure cast properly dominates Builder's IP. The selected cast must properly dominate the Builder's IP, so we cannot re-use the cast, if it matches the builder's IP. --- .../Utils/ScalarEvolutionExpander.cpp | 5 +- .../X86/expander-crashes.ll | 85 +++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index ade2cfa30dd055..da6a719dccd1b7 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -65,8 +65,9 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty, if (!CI || CI->getOpcode() != Op) continue; - // Found a suitable cast that is at IP or comes before IP. Use it. - if (IP->getParent() == CI->getParent() && + // Found a suitable cast that is at IP or comes before IP. Use it. Note that + // the cast must also properly dominate the Builder's insertion point. + if (IP->getParent() == CI->getParent() && &*BIP != CI && (&*IP == CI || CI->comesBefore(&*IP))) { Ret = CI; break; diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll new file mode 100644 index 00000000000000..c895a10ba11054 --- /dev/null +++ b/llvm/test/Transforms/LoopStrengthReduce/X86/expander-crashes.ll @@ -0,0 +1,85 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -loop-reduce %s -S | FileCheck %s + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.15.0" + +; Tests for crashes during SCEV expansion. + +%struct.hoge = type { i32, i32, i32, i32 } + +define i64 @blam(%struct.hoge* %start, %struct.hoge* %end, %struct.hoge* %ptr.2) { +; CHECK-LABEL: @blam( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[END16:%.*]] = bitcast %struct.hoge* [[END:%.*]] to i8* +; CHECK-NEXT: [[START17:%.*]] = ptrtoint %struct.hoge* [[START:%.*]] to i64 +; CHECK-NEXT: [[SCEVGEP12:%.*]] = getelementptr [[STRUCT_HOGE:%.*]], %struct.hoge* [[START]], i64 0, i32 3 +; CHECK-NEXT: [[SCEVGEP1213:%.*]] = bitcast i32* [[SCEVGEP12]] to %struct.hoge* +; CHECK-NEXT: [[TMP0:%.*]] = sub i64 0, [[START17]] +; CHECK-NEXT: [[UGLYGEP18:%.*]] = getelementptr i8, i8* [[END16]], i64 [[TMP0]] +; CHECK-NEXT: [[UGLYGEP1819:%.*]] = bitcast i8* [[UGLYGEP18]] to %struct.hoge* +; CHECK-NEXT: br label [[LOOP_1_HEADER:%.*]] +; CHECK: loop.1.header: +; CHECK-NEXT: [[LSR_IV20:%.*]] = phi %struct.hoge* [ [[SCEVGEP21:%.*]], [[LOOP_1_HEADER]] ], [ [[UGLYGEP1819]], [[ENTRY:%.*]] ] +; CHECK-NEXT: [[LSR_IV14:%.*]] = phi %struct.hoge* [ [[SCEVGEP15:%.*]], [[LOOP_1_HEADER]] ], [ [[SCEVGEP1213]], [[ENTRY]] ] +; CHECK-NEXT: [[SCEVGEP15]] = getelementptr [[STRUCT_HOGE]], %struct.hoge* [[LSR_IV14]], i64 1 +; CHECK-NEXT: [[SCEVGEP21]] = getelementptr [[STRUCT_HOGE]], %struct.hoge* [[LSR_IV20]], i64 -1 +; CHECK-NEXT: [[EC:%.*]] = icmp eq %struct.hoge* [[SCEVGEP21]], null +; CHECK-NEXT: br i1 [[EC]], label [[LOOP_2_PH:%.*]], label [[LOOP_1_HEADER]] +; CHECK: loop.2.ph: +; CHECK-NEXT: br label [[LOOP_2_HEADER:%.*]] +; CHECK: loop.2.header: +; CHECK-NEXT: [[LSR_IV3:%.*]] = phi %struct.hoge* [ [[SCEVGEP4:%.*]], [[LOOP_2_LATCH:%.*]] ], [ [[SCEVGEP15]], [[LOOP_2_PH]] ] +; CHECK-NEXT: [[LSR_IV310:%.*]] = bitcast %struct.hoge* [[LSR_IV3]] to i32* +; CHECK-NEXT: [[LSR_IV37:%.*]] = bitcast %struct.hoge* [[LSR_IV3]] to i8* +; CHECK-NEXT: [[UGLYGEP8:%.*]] = getelementptr i8, i8* [[LSR_IV37]], i64 -12 +; CHECK-NEXT: [[UGLYGEP89:%.*]] = bitcast i8* [[UGLYGEP8]] to %struct.hoge* +; CHECK-NEXT: [[LSR_IV35:%.*]] = bitcast %struct.hoge* [[LSR_IV3]] to i8* +; CHECK-NEXT: [[TMP8:%.*]] = ptrtoint i32* [[LSR_IV310]] to i64 +; CHECK-NEXT: call void @use.i64(i64 [[TMP8]]) +; CHECK-NEXT: [[SCEVGEP11:%.*]] = getelementptr i32, i32* [[LSR_IV310]], i64 -1 +; CHECK-NEXT: store i32 10, i32* [[SCEVGEP11]], align 8 +; CHECK-NEXT: [[EC_2:%.*]] = icmp ugt %struct.hoge* [[UGLYGEP89]], [[PTR_2:%.*]] +; CHECK-NEXT: br i1 [[EC_2]], label [[LOOP_2_EXIT:%.*]], label [[LOOP_2_LATCH]] +; CHECK: loop.2.latch: +; CHECK-NEXT: [[SCEVGEP4]] = getelementptr [[STRUCT_HOGE]], %struct.hoge* [[LSR_IV3]], i64 1 +; CHECK-NEXT: br label [[LOOP_2_HEADER]] +; CHECK: loop.2.exit: +; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* [[LSR_IV35]], i64 -12 +; CHECK-NEXT: [[UGLYGEP6:%.*]] = bitcast i8* [[UGLYGEP]] to %struct.hoge* +; CHECK-NEXT: [[IV2_CAST:%.*]] = ptrtoint %struct.hoge* [[UGLYGEP6]] to i64 +; CHECK-NEXT: ret i64 [[IV2_CAST]] +; +entry: + br label %loop.1.header + +loop.1.header: + %iv = phi %struct.hoge* [ %iv.next, %loop.1.header ], [ %start, %entry ] + %iv.next = getelementptr inbounds %struct.hoge, %struct.hoge* %iv, i64 1 + %ec = icmp eq %struct.hoge* %iv.next, %end + br i1 %ec, label %loop.2.ph, label %loop.1.header + +loop.2.ph: + br label %loop.2.header + +loop.2.header: + %iv2 = phi %struct.hoge* [ %iv2.next, %loop.2.latch ], [ %iv.next, %loop.2.ph ] + %tmp7 = getelementptr inbounds %struct.hoge, %struct.hoge* %iv2, i64 0, i32 3 + %tmp8 = ptrtoint i32* %tmp7 to i64 + call void @use.i64(i64 %tmp8) + %tmp9 = getelementptr inbounds %struct.hoge, %struct.hoge* %iv2, i64 0, i32 2 + store i32 10, i32* %tmp9, align 8 + %ec.2 = icmp ugt %struct.hoge* %iv2, %ptr.2 + br i1 %ec.2, label %loop.2.exit, label %loop.2.latch + +loop.2.latch: + %iv2.next = getelementptr inbounds %struct.hoge, %struct.hoge* %iv2, i64 1 + br label %loop.2.header + +loop.2.exit: ; preds = %bb6 + %iv2.cast = ptrtoint %struct.hoge* %iv2 to i64 + ret i64 %iv2.cast +} + + +declare void @use.i64(i64)