From ac02bf666246a92801107fe2107b16a708955517 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 12 Apr 2023 10:17:28 +0200 Subject: [PATCH] [GVNHoist] Regenerate test checks (NFC) --- .../Transforms/GVNHoist/infinite-loop-indirect.ll | 227 +++++++++++++++------ 1 file changed, 169 insertions(+), 58 deletions(-) diff --git a/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll b/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll index 316ee20..2621b71 100644 --- a/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll +++ b/llvm/test/Transforms/GVNHoist/infinite-loop-indirect.ll @@ -1,21 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 ; RUN: opt -S -passes=gvn-hoist < %s | FileCheck %s ; Checking gvn-hoist in case of indirect branches. -; Check that the bitcast is not hoisted because it is after an indirect call -; CHECK-LABEL: @foo -; CHECK-LABEL: l1.preheader: -; CHECK-NEXT: bitcast -; CHECK-LABEL: l1 -; CHECK: bitcast - %class.bar = type { i8*, %class.base* } %class.base = type { i32 (...)** } @bar = local_unnamed_addr global i32 ()* null, align 8 @bar1 = local_unnamed_addr global i32 ()* null, align 8 +; Check that the bitcast is not hoisted because it is after an indirect call define i32 @foo(i32* nocapture readonly %i) { +; CHECK-LABEL: define i32 @foo +; CHECK-SAME: (ptr nocapture readonly [[I:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8 +; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1 +; CHECK-NEXT: [[Y:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4 +; CHECK-NEXT: [[DOTOFF:%.*]] = add i32 [[TMP0]], -1 +; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[DOTOFF]], 2 +; CHECK-NEXT: br i1 [[SWITCH]], label [[L1_PREHEADER:%.*]], label [[SW_DEFAULT:%.*]] +; CHECK: l1.preheader: +; CHECK-NEXT: [[B1:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: br label [[L1:%.*]] +; CHECK: l1: +; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @bar, align 8 +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]]() +; CHECK-NEXT: [[B2:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: br label [[L1]] +; CHECK: sw.default: +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr @bar1, align 8 +; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 [[TMP2]]() +; CHECK-NEXT: br label [[L1_PREHEADER]] +; entry: %agg.tmp = alloca %class.bar, align 8 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 @@ -44,14 +62,32 @@ sw.default: ; preds = %entry ; Any instruction inside an infinite loop will not be hoisted because ; there is no path to exit of the function. - -; CHECK-LABEL: @foo1 -; CHECK-LABEL: l1.preheader: -; CHECK-NEXT: bitcast -; CHECK-LABEL: l1: -; CHECK: bitcast - define i32 @foo1(i32* nocapture readonly %i) { +; CHECK-LABEL: define i32 @foo1 +; CHECK-SAME: (ptr nocapture readonly [[I:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8 +; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1 +; CHECK-NEXT: [[Y:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4 +; CHECK-NEXT: [[DOTOFF:%.*]] = add i32 [[TMP0]], -1 +; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[DOTOFF]], 2 +; CHECK-NEXT: br i1 [[SWITCH]], label [[L1_PREHEADER:%.*]], label [[SW_DEFAULT:%.*]] +; CHECK: l1.preheader: +; CHECK-NEXT: [[B1:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: [[Y1:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: br label [[L1:%.*]] +; CHECK: l1: +; CHECK-NEXT: [[B2:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @bar, align 8 +; CHECK-NEXT: [[Y2:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]]() +; CHECK-NEXT: br label [[L1]] +; CHECK: sw.default: +; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr @bar1, align 8 +; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 [[TMP2]]() +; CHECK-NEXT: br label [[L1_PREHEADER]] +; entry: %agg.tmp = alloca %class.bar, align 8 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 @@ -80,11 +116,27 @@ sw.default: ; preds = %entry } ; Check that bitcast is hoisted even when one of them is partially redundant. -; CHECK-LABEL: @test13 -; CHECK: bitcast -; CHECK-NOT: bitcast - define i32 @test13(i32* %P, i8* %Ptr, i32* nocapture readonly %i) { +; CHECK-LABEL: define i32 @test13 +; CHECK-SAME: (ptr [[P:%.*]], ptr [[PTR:%.*]], ptr nocapture readonly [[I:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8 +; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1 +; CHECK-NEXT: [[Y:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: [[B2:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: indirectbr ptr [[PTR]], [label [[BRBLOCK:%.*]], label %B2] +; CHECK: B2: +; CHECK-NEXT: store i32 4, ptr [[P]], align 4 +; CHECK-NEXT: br label [[BRBLOCK]] +; CHECK: BrBlock: +; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 42 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT: ret i32 123 +; CHECK: F: +; CHECK-NEXT: ret i32 1422 +; entry: %agg.tmp = alloca %class.bar, align 8 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 @@ -111,14 +163,30 @@ F: ; Check that the bitcast is not hoisted because anticipability ; cannot be guaranteed here as one of the indirect branch targets ; do not have the bitcast instruction. - -; CHECK-LABEL: @test14 -; CHECK-LABEL: B2: -; CHECK-NEXT: bitcast -; CHECK-LABEL: BrBlock: -; CHECK-NEXT: bitcast - define i32 @test14(i32* %P, i8* %Ptr, i32* nocapture readonly %i) { +; CHECK-LABEL: define i32 @test14 +; CHECK-SAME: (ptr [[P:%.*]], ptr [[PTR:%.*]], ptr nocapture readonly [[I:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8 +; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1 +; CHECK-NEXT: [[Y:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: indirectbr ptr [[PTR]], [label [[BRBLOCK:%.*]], label [[B2:%.*]], label %T] +; CHECK: B2: +; CHECK-NEXT: [[B1:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: store i32 4, ptr [[P]], align 4 +; CHECK-NEXT: br label [[BRBLOCK]] +; CHECK: BrBlock: +; CHECK-NEXT: [[B2:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 42 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT: [[PI:%.*]] = load i32, ptr [[I]], align 4 +; CHECK-NEXT: ret i32 [[PI]] +; CHECK: F: +; CHECK-NEXT: [[PL:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: ret i32 [[PL]] +; entry: %agg.tmp = alloca %class.bar, align 8 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 @@ -147,13 +215,29 @@ F: ; Check that the bitcast is not hoisted because of a cycle ; due to indirect branches -; CHECK-LABEL: @test16 -; CHECK-LABEL: B2: -; CHECK-NEXT: bitcast -; CHECK-LABEL: BrBlock: -; CHECK-NEXT: bitcast - define i32 @test16(i32* %P, i8* %Ptr, i32* nocapture readonly %i) { +; CHECK-LABEL: define i32 @test16 +; CHECK-SAME: (ptr [[P:%.*]], ptr [[PTR:%.*]], ptr nocapture readonly [[I:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8 +; CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1 +; CHECK-NEXT: [[Y:%.*]] = load ptr, ptr [[X]], align 8 +; CHECK-NEXT: indirectbr ptr [[PTR]], [label [[BRBLOCK:%.*]], label %B2] +; CHECK: B2: +; CHECK-NEXT: [[B1:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4 +; CHECK-NEXT: store i32 [[TMP0]], ptr [[P]], align 4 +; CHECK-NEXT: br label [[BRBLOCK]] +; CHECK: BrBlock: +; CHECK-NEXT: [[B2:%.*]] = bitcast ptr [[Y]] to ptr +; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4 +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 42 +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT: indirectbr ptr [[P]], [label [[BRBLOCK]], label %B2] +; CHECK: F: +; CHECK-NEXT: indirectbr ptr [[PTR]], [label [[BRBLOCK]], label %B2] +; entry: %agg.tmp = alloca %class.bar, align 8 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 @@ -188,28 +272,55 @@ F: ; landing pad has direct branches (e.g., %lpad to %catch1, %catch) ; This CFG has a cycle (%lpad -> %catch1 -> %lpad4 -> %lpad) -; CHECK-LABEL: @foo2 -; Check that nothing gets hoisted out of %lpad -; CHECK-LABEL: lpad: -; CHECK: %bc1 = add i32 %0, 10 -; CHECK: %bc7 = add i32 %0, 10 - -; Check that the add is hoisted -; CHECK-LABEL: catch1: -; CHECK-NEXT: invoke - -; Check that the add is hoisted -; CHECK-LABEL: catch: -; CHECK-NEXT: load - -; Check that other adds are not hoisted -; CHECK-LABEL: lpad4: -; CHECK: %bc5 = add i32 %0, 10 -; CHECK-LABEL: unreachable: -; CHECK: %bc2 = add i32 %0, 10 - -; Function Attrs: noinline uwtable define i32 @foo2(i32* nocapture readonly %i) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +; CHECK-LABEL: define i32 @foo2 +; CHECK-SAME: (ptr nocapture readonly [[I:%.*]]) local_unnamed_addr personality ptr @__gxx_personality_v0 { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[I]], align 4 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[CMP]], label [[TRY_CONT:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[EXCEPTION:%.*]] = tail call ptr @__cxa_allocate_exception(i64 4) #[[ATTR1:[0-9]+]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast ptr [[EXCEPTION]] to ptr +; CHECK-NEXT: store i32 [[TMP0]], ptr [[TMP1]], align 16 +; CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIi, ptr null) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]] +; CHECK: lpad: +; CHECK-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } +; CHECK-NEXT: catch ptr @_ZTIi +; CHECK-NEXT: catch ptr null +; CHECK-NEXT: [[BC1:%.*]] = add i32 [[TMP0]], 10 +; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0 +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1 +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #[[ATTR1]] +; CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP4]], [[TMP5]] +; CHECK-NEXT: [[BC7:%.*]] = add i32 [[TMP0]], 10 +; CHECK-NEXT: [[TMP6:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP3]]) #[[ATTR1]] +; CHECK-NEXT: [[BC4:%.*]] = add i32 [[TMP0]], 10 +; CHECK-NEXT: br i1 [[MATCHES]], label [[CATCH1:%.*]], label [[CATCH:%.*]] +; CHECK: catch1: +; CHECK-NEXT: invoke void @__cxa_rethrow() #[[ATTR2]] +; CHECK-NEXT: to label [[UNREACHABLE]] unwind label [[LPAD4:%.*]] +; CHECK: catch: +; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[I]], align 4 +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP7]], 1 +; CHECK-NEXT: tail call void @__cxa_end_catch() +; CHECK-NEXT: br label [[TRY_CONT]] +; CHECK: lpad4: +; CHECK-NEXT: [[TMP8:%.*]] = landingpad { ptr, i32 } +; CHECK-NEXT: cleanup +; CHECK-NEXT: [[BC5:%.*]] = add i32 [[TMP0]], 10 +; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR1]] +; CHECK-NEXT: invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIi, ptr null) #[[ATTR2]] +; CHECK-NEXT: to label [[UNREACHABLE]] unwind label [[LPAD]] +; CHECK: try.cont: +; CHECK-NEXT: [[K_0:%.*]] = phi i32 [ [[ADD]], [[CATCH]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[BC6:%.*]] = add i32 [[TMP0]], 10 +; CHECK-NEXT: ret i32 [[K_0]] +; CHECK: unreachable: +; CHECK-NEXT: [[BC2:%.*]] = add i32 [[TMP0]], 10 +; CHECK-NEXT: ret i32 [[BC2]] +; entry: %0 = load i32, i32* %i, align 4 %cmp = icmp eq i32 %0, 0 @@ -220,12 +331,12 @@ if.then: %1 = bitcast i8* %exception to i32* store i32 %0, i32* %1, align 16 invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3 - to label %unreachable unwind label %lpad + to label %unreachable unwind label %lpad lpad: %2 = landingpad { i8*, i32 } - catch i8* bitcast (i8** @_ZTIi to i8*) - catch i8* null + catch i8* bitcast (i8** @_ZTIi to i8*) + catch i8* null %bc1 = add i32 %0, 10 %3 = extractvalue { i8*, i32 } %2, 0 %4 = extractvalue { i8*, i32 } %2, 1 @@ -238,7 +349,7 @@ lpad: catch1: %bc3 = add i32 %0, 10 invoke void @__cxa_rethrow() #3 - to label %unreachable unwind label %lpad4 + to label %unreachable unwind label %lpad4 catch: %bc4 = add i32 %0, 10 @@ -249,11 +360,11 @@ catch: lpad4: %8 = landingpad { i8*, i32 } - cleanup + cleanup %bc5 = add i32 %0, 10 tail call void @__cxa_end_catch() #2 invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3 - to label %unreachable unwind label %lpad + to label %unreachable unwind label %lpad try.cont: %k.0 = phi i32 [ %add, %catch ], [ 0, %entry ] -- 2.7.4