From e6e6404600281d4ae34162a5853e7a9cdbe50d44 Mon Sep 17 00:00:00 2001 From: Juneyoung Lee Date: Wed, 30 Dec 2020 22:13:10 +0900 Subject: [PATCH] [SimplifyCFG] Add tests for select form and/or for creating select from icmps --- llvm/test/Transforms/SimplifyCFG/switch_create.ll | 139 ++++++++++++++++++++-- 1 file changed, 132 insertions(+), 7 deletions(-) diff --git a/llvm/test/Transforms/SimplifyCFG/switch_create.ll b/llvm/test/Transforms/SimplifyCFG/switch_create.ll index 3314fc9..cc7a489 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch_create.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch_create.ll @@ -31,6 +31,31 @@ F: ; preds = %0 ret void } +define void @test1_select(i32 %V) { +; CHECK-LABEL: @test1_select( +; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[V:%.*]], 4 +; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[V]], 17 +; CHECK-NEXT: [[CN:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]] +; CHECK-NEXT: br i1 [[CN]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT: call void @foo1() +; CHECK-NEXT: ret void +; CHECK: F: +; CHECK-NEXT: call void @foo2() +; CHECK-NEXT: ret void +; + %C1 = icmp eq i32 %V, 4 + %C2 = icmp eq i32 %V, 17 + %CN = select i1 %C1, i1 true, i1 %C2 + br i1 %CN, label %T, label %F +T: + call void @foo1( ) + ret void +F: + call void @foo2( ) + ret void +} + define void @test1_ptr(i32* %V) { ; DL-LABEL: @test1_ptr( ; DL-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32* [[V:%.*]] to i32 @@ -108,6 +133,31 @@ F: ; preds = %0 ret void } +define void @test2_select(i32 %V) { +; CHECK-LABEL: @test2_select( +; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[V:%.*]], 4 +; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[V]], 17 +; CHECK-NEXT: [[CN:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false +; CHECK-NEXT: br i1 [[CN]], label [[T:%.*]], label [[F:%.*]] +; CHECK: T: +; CHECK-NEXT: call void @foo1() +; CHECK-NEXT: ret void +; CHECK: F: +; CHECK-NEXT: call void @foo2() +; CHECK-NEXT: ret void +; + %C1 = icmp ne i32 %V, 4 + %C2 = icmp ne i32 %V, 17 + %CN = select i1 %C1, i1 %C2, i1 false + br i1 %CN, label %T, label %F +T: + call void @foo1( ) + ret void +F: + call void @foo2( ) + ret void +} + define void @test3(i32 %V) { ; CHECK-LABEL: @test3( ; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [ @@ -208,7 +258,7 @@ define i1 @test6({ i32, i32 }* %I) { ; CHECK-LABEL: @test6( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1 -; CHECK-NEXT: [[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]] +; CHECK-NEXT: [[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]], align 4 ; CHECK-NEXT: [[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14 ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6 ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false @@ -253,7 +303,7 @@ define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone { ; CHECK-NEXT: i8 97, label [[IF_THEN]] ; CHECK-NEXT: ] ; CHECK: if.then: -; CHECK-NEXT: tail call void @foo1() #2 +; CHECK-NEXT: tail call void @foo1() [[ATTR2:#.*]] ; CHECK-NEXT: ret void ; CHECK: if.end: ; CHECK-NEXT: ret void @@ -289,7 +339,7 @@ define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { ; CHECK-NEXT: ] ; CHECK: if.then: ; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ] -; CHECK-NEXT: tail call void @foo1() #2 +; CHECK-NEXT: tail call void @foo1() [[ATTR2]] ; CHECK-NEXT: ret i32 [[A]] ; CHECK: if.end: ; CHECK-NEXT: ret i32 0 @@ -413,6 +463,28 @@ F: } +define i32 @test10_select(i32 %mode, i1 %Cond) { +; CHECK-LABEL: @test10_select( +; CHECK-NEXT: T: +; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[MODE:%.*]], 0 +; CHECK-NEXT: [[B:%.*]] = icmp ne i32 [[MODE]], 51 +; CHECK-NEXT: [[C:%.*]] = select i1 [[A]], i1 [[B]], i1 false +; CHECK-NEXT: [[D:%.*]] = and i1 [[C]], [[COND:%.*]] +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[D]], i32 123, i32 324 +; CHECK-NEXT: ret i32 [[SPEC_SELECT]] +; + %A = icmp ne i32 %mode, 0 + %B = icmp ne i32 %mode, 51 + %C = select i1 %A, i1 %B, i1 false + %D = and i1 %C, %Cond + br i1 %D, label %T, label %F +T: + ret i32 123 +F: + ret i32 324 + +} + ; PR8780 define i32 @test11(i32 %bar) nounwind { ; CHECK-LABEL: @test11( @@ -465,8 +537,8 @@ return: ; preds = %if.end, %if.then define void @test12() nounwind { ; CHECK-LABEL: @test12( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[A_OLD:%.*]] = icmp eq i32 undef, undef -; CHECK-NEXT: br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]] +; CHECK-NEXT: [[DOTOLD:%.*]] = icmp eq i32 undef, undef +; CHECK-NEXT: br i1 [[DOTOLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]] ; CHECK: bb55.us.us: ; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 undef, undef ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 undef, undef @@ -506,7 +578,7 @@ define void @test13(i32 %x) nounwind ssp noredzone { ; CHECK-NEXT: i32 0, label [[IF_THEN]] ; CHECK-NEXT: ] ; CHECK: if.then: -; CHECK-NEXT: call void @foo1() #3 +; CHECK-NEXT: call void @foo1() [[ATTR3:#.*]] ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: ret void @@ -548,7 +620,7 @@ define void @test14(i32 %x) nounwind ssp noredzone { ; CHECK-NEXT: i32 0, label [[IF_THEN]] ; CHECK-NEXT: ] ; CHECK: if.then: -; CHECK-NEXT: call void @foo1() #3 +; CHECK-NEXT: call void @foo1() [[ATTR3]] ; CHECK-NEXT: br label [[IF_END]] ; CHECK: if.end: ; CHECK-NEXT: ret void @@ -654,6 +726,32 @@ return: } +define void @test17_select(i32 %x, i32 %y) { +; CHECK-LABEL: @test17_select( +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3 +; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2 +; CHECK-NEXT: [[OR_COND775:%.*]] = select i1 [[CMP]], i1 true, i1 [[SWITCH]] +; CHECK-NEXT: br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[RETURN:%.*]] +; CHECK: lor.lhs.false8: +; CHECK-NEXT: tail call void @foo1() +; CHECK-NEXT: ret void +; CHECK: return: +; CHECK-NEXT: ret void +; + %cmp = icmp ult i32 %x, 3 + %switch = icmp ult i32 %y, 2 + %or.cond775 = select i1 %cmp, i1 true, i1 %switch + br i1 %or.cond775, label %lor.lhs.false8, label %return + +lor.lhs.false8: + tail call void @foo1() + ret void + +return: + ret void + +} + define void @test18(i32 %arg) { ; CHECK-LABEL: @test18( ; CHECK-NEXT: bb: @@ -758,6 +856,33 @@ else: ret void } +define void @test19_select(i32 %arg) { +; CHECK-LABEL: @test19_select( +; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARG:%.*]], -2 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 12 +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32 +; CHECK-NEXT: [[PRED:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]] +; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]] +; CHECK: if: +; CHECK-NEXT: call void @foo1() +; CHECK-NEXT: ret void +; CHECK: else: +; CHECK-NEXT: ret void +; + %and = and i32 %arg, -2 + %cmp1 = icmp eq i32 %and, 12 + %cmp2 = icmp eq i32 %arg, 32 + %pred = select i1 %cmp1, i1 true, i1 %cmp2 + br i1 %pred, label %if, label %else + +if: + call void @foo1() + ret void + +else: + ret void +} + ; Since %cmp1 is always false, a switch is never formed define void @test20(i32 %arg) { ; CHECK-LABEL: @test20( -- 2.7.4