brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.0 KiB · c53d86d Raw
243 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=mergeicmps -verify-dom-info -mtriple=x86_64-unknown-unknown -S | FileCheck %s --check-prefix=X863 4%S = type { i32, i32, i32, i32 }5 6declare void @foo(...)7 8; We can split %entry and create a memcmp(16 bytes).9define zeroext i1 @opeq1(10; X86-LABEL: @opeq1(11; X86-NEXT:  "entry+land.rhs.i+land.rhs.i.2+land.rhs.i.3":12; X86-NEXT:    call void (...) @foo() #[[ATTR2:[0-9]+]]13; X86-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr [[A:%.*]], ptr [[B:%.*]], i64 16)14; X86-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[MEMCMP]], 015; X86-NEXT:    br label [[OPEQ1_EXIT:%.*]]16; X86:       opeq1.exit:17; X86-NEXT:    ret i1 [[TMP2]]18;19; Make sure this call is moved to the beginning of the entry block.20  ptr nocapture readonly dereferenceable(16) %a,21  ptr nocapture readonly dereferenceable(16) %b) local_unnamed_addr nofree nosync {22entry:23  %0 = load i32, ptr %a, align 424  %1 = load i32, ptr %b, align 425  ; Does other work.26  call void (...) @foo() inaccessiblememonly27  %cmp.i = icmp eq i32 %0, %128  br i1 %cmp.i, label %land.rhs.i, label %opeq1.exit29 30land.rhs.i:31  %second.i = getelementptr inbounds %S, ptr %a, i64 0, i32 132  %2 = load i32, ptr %second.i, align 433  %second2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 134  %3 = load i32, ptr %second2.i, align 435  %cmp2.i = icmp eq i32 %2, %336  br i1 %cmp2.i, label %land.rhs.i.2, label %opeq1.exit37 38land.rhs.i.2:39  %third.i = getelementptr inbounds %S, ptr %a, i64 0, i32 240  %4 = load i32, ptr %third.i, align 441  %third2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 242  %5 = load i32, ptr %third2.i, align 443  %cmp3.i = icmp eq i32 %4, %544  br i1 %cmp3.i, label %land.rhs.i.3, label %opeq1.exit45 46land.rhs.i.3:47  %fourth.i = getelementptr inbounds %S, ptr %a, i64 0, i32 348  %6 = load i32, ptr %fourth.i, align 449  %fourth2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 350  %7 = load i32, ptr %fourth2.i, align 451  %cmp4.i = icmp eq i32 %6, %752  br label %opeq1.exit53 54opeq1.exit:55  %8 = phi i1 [ false, %entry ], [ false, %land.rhs.i] , [ false, %land.rhs.i.2 ], [ %cmp4.i, %land.rhs.i.3 ]56  ret i1 %857}58 59 60; We will not be able to merge anything, make sure the call is not moved out.61define zeroext i1 @opeq1_discontiguous(62; X86-LABEL: @opeq1_discontiguous(63; X86-NEXT:  entry:64; X86-NEXT:    [[FIRST_I:%.*]] = getelementptr inbounds [[S:%.*]], ptr [[A:%.*]], i64 0, i32 165; X86-NEXT:    [[TMP0:%.*]] = load i32, ptr [[FIRST_I]], align 466; X86-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B:%.*]], align 467; X86-NEXT:    call void (...) @foo() #[[ATTR2]]68; X86-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]69; X86-NEXT:    br i1 [[CMP_I]], label [[LAND_RHS_I:%.*]], label [[OPEQ1_EXIT:%.*]]70; X86:       land.rhs.i:71; X86-NEXT:    [[SECOND_I:%.*]] = getelementptr inbounds [[S]], ptr [[A]], i64 0, i32 272; X86-NEXT:    [[TMP2:%.*]] = load i32, ptr [[SECOND_I]], align 473; X86-NEXT:    [[SECOND2_I:%.*]] = getelementptr inbounds [[S]], ptr [[B]], i64 0, i32 174; X86-NEXT:    [[TMP3:%.*]] = load i32, ptr [[SECOND2_I]], align 475; X86-NEXT:    [[CMP2_I:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]]76; X86-NEXT:    br i1 [[CMP2_I]], label [[LAND_RHS_I_2:%.*]], label [[OPEQ1_EXIT]]77; X86:       land.rhs.i.2:78; X86-NEXT:    [[THIRD_I:%.*]] = getelementptr inbounds [[S]], ptr [[A]], i64 0, i32 279; X86-NEXT:    [[TMP4:%.*]] = load i32, ptr [[THIRD_I]], align 480; X86-NEXT:    [[THIRD2_I:%.*]] = getelementptr inbounds [[S]], ptr [[B]], i64 0, i32 381; X86-NEXT:    [[TMP5:%.*]] = load i32, ptr [[THIRD2_I]], align 482; X86-NEXT:    [[CMP3_I:%.*]] = icmp eq i32 [[TMP4]], [[TMP5]]83; X86-NEXT:    br i1 [[CMP3_I]], label [[LAND_RHS_I_3:%.*]], label [[OPEQ1_EXIT]]84; X86:       land.rhs.i.3:85; X86-NEXT:    [[FOURTH_I:%.*]] = getelementptr inbounds [[S]], ptr [[A]], i64 0, i32 186; X86-NEXT:    [[TMP6:%.*]] = load i32, ptr [[FOURTH_I]], align 487; X86-NEXT:    [[FOURTH2_I:%.*]] = getelementptr inbounds [[S]], ptr [[B]], i64 0, i32 388; X86-NEXT:    [[TMP7:%.*]] = load i32, ptr [[FOURTH2_I]], align 489; X86-NEXT:    [[CMP4_I:%.*]] = icmp eq i32 [[TMP6]], [[TMP7]]90; X86-NEXT:    br label [[OPEQ1_EXIT]]91; X86:       opeq1.exit:92; X86-NEXT:    [[TMP8:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ false, [[LAND_RHS_I]] ], [ false, [[LAND_RHS_I_2]] ], [ [[CMP4_I]], [[LAND_RHS_I_3]] ]93; X86-NEXT:    ret i1 [[TMP8]]94;95; Make sure this call is moved in the entry block.96  ptr nocapture readonly dereferenceable(16) %a,97  ptr nocapture readonly dereferenceable(16) %b) local_unnamed_addr #0 {98entry:99  %first.i = getelementptr inbounds %S, ptr %a, i64 0, i32 1100  %0 = load i32, ptr %first.i, align 4101  %1 = load i32, ptr %b, align 4102  ; Does other work.103  call void (...) @foo() inaccessiblememonly104  %cmp.i = icmp eq i32 %0, %1105  br i1 %cmp.i, label %land.rhs.i, label %opeq1.exit106 107land.rhs.i:108  %second.i = getelementptr inbounds %S, ptr %a, i64 0, i32 2109  %2 = load i32, ptr %second.i, align 4110  %second2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 1111  %3 = load i32, ptr %second2.i, align 4112  %cmp2.i = icmp eq i32 %2, %3113  br i1 %cmp2.i, label %land.rhs.i.2, label %opeq1.exit114 115land.rhs.i.2:116  %third.i = getelementptr inbounds %S, ptr %a, i64 0, i32 2117  %4 = load i32, ptr %third.i, align 4118  %third2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 3119  %5 = load i32, ptr %third2.i, align 4120  %cmp3.i = icmp eq i32 %4, %5121  br i1 %cmp3.i, label %land.rhs.i.3, label %opeq1.exit122 123land.rhs.i.3:124  %fourth.i = getelementptr inbounds %S, ptr %a, i64 0, i32 1125  %6 = load i32, ptr %fourth.i, align 4126  %fourth2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 3127  %7 = load i32, ptr %fourth2.i, align 4128  %cmp4.i = icmp eq i32 %6, %7129  br label %opeq1.exit130 131opeq1.exit:132  %8 = phi i1 [ false, %entry ], [ false, %land.rhs.i] , [ false, %land.rhs.i.2 ], [ %cmp4.i, %land.rhs.i.3 ]133  ret i1 %8134}135 136; The call happens before the loads, so it cannot clobber them.137define zeroext i1 @opeq1_call_before_loads(138; X86-LABEL: @opeq1_call_before_loads(139; X86-NEXT:  "entry+land.rhs.i+land.rhs.i.2+land.rhs.i.3":140; X86-NEXT:    call void (...) @foo()141; X86-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr [[A:%.*]], ptr [[B:%.*]], i64 16)142; X86-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[MEMCMP]], 0143; X86-NEXT:    br label [[OPEQ1_EXIT:%.*]]144; X86:       opeq1.exit:145; X86-NEXT:    ret i1 [[TMP2]]146;147; Make sure this call is moved to the beginning of the entry block.148  ptr nocapture readonly dereferenceable(16) %a,149  ptr nocapture readonly dereferenceable(16) %b) local_unnamed_addr nofree nosync {150entry:151  call void (...) @foo()152  %0 = load i32, ptr %a, align 4153  %1 = load i32, ptr %b, align 4154  %cmp.i = icmp eq i32 %0, %1155  br i1 %cmp.i, label %land.rhs.i, label %opeq1.exit156 157land.rhs.i:158  %second.i = getelementptr inbounds %S, ptr %a, i64 0, i32 1159  %2 = load i32, ptr %second.i, align 4160  %second2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 1161  %3 = load i32, ptr %second2.i, align 4162  %cmp2.i = icmp eq i32 %2, %3163  br i1 %cmp2.i, label %land.rhs.i.2, label %opeq1.exit164 165land.rhs.i.2:166  %third.i = getelementptr inbounds %S, ptr %a, i64 0, i32 2167  %4 = load i32, ptr %third.i, align 4168  %third2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 2169  %5 = load i32, ptr %third2.i, align 4170  %cmp3.i = icmp eq i32 %4, %5171  br i1 %cmp3.i, label %land.rhs.i.3, label %opeq1.exit172 173land.rhs.i.3:174  %fourth.i = getelementptr inbounds %S, ptr %a, i64 0, i32 3175  %6 = load i32, ptr %fourth.i, align 4176  %fourth2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 3177  %7 = load i32, ptr %fourth2.i, align 4178  %cmp4.i = icmp eq i32 %6, %7179  br label %opeq1.exit180 181opeq1.exit:182  %8 = phi i1 [ false, %entry ], [ false, %land.rhs.i] , [ false, %land.rhs.i.2 ], [ %cmp4.i, %land.rhs.i.3 ]183  ret i1 %8184}185 186; Call happens after the loads, and may clobber them.187define zeroext i1 @opeq1_call_after_loads(188; X86-LABEL: @opeq1_call_after_loads(189; X86-NEXT:  entry:190; X86-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A:%.*]], align 4191; X86-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B:%.*]], align 4192; X86-NEXT:    call void (...) @foo()193; X86-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]194; X86-NEXT:    br i1 [[CMP_I]], label %"land.rhs.i+land.rhs.i.2+land.rhs.i.3", label [[OPEQ1_EXIT:%.*]]195; X86:       "land.rhs.i+land.rhs.i.2+land.rhs.i.3":196; X86-NEXT:    [[TMP2:%.*]] = getelementptr inbounds [[S]], ptr [[A]], i64 0, i32 1197; X86-NEXT:    [[TMP3:%.*]] = getelementptr inbounds [[S]], ptr [[B]], i64 0, i32 1198; X86-NEXT:    [[MEMCMP:%.*]] = call i32 @memcmp(ptr [[TMP2]], ptr [[TMP3]], i64 12)199; X86-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[MEMCMP]], 0200; X86-NEXT:    br label [[OPEQ1_EXIT]]201; X86:       opeq1.exit:202; X86-NEXT:    [[TMP5:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[TMP4]], %"land.rhs.i+land.rhs.i.2+land.rhs.i.3" ]203; X86-NEXT:    ret i1 [[TMP5]]204;205; Make sure this call is moved to the beginning of the entry block.206  ptr nocapture readonly dereferenceable(16) %a,207  ptr nocapture readonly dereferenceable(16) %b) local_unnamed_addr nofree nosync {208entry:209  %0 = load i32, ptr %a, align 4210  %1 = load i32, ptr %b, align 4211  call void (...) @foo()212  %cmp.i = icmp eq i32 %0, %1213  br i1 %cmp.i, label %land.rhs.i, label %opeq1.exit214 215land.rhs.i:216  %second.i = getelementptr inbounds %S, ptr %a, i64 0, i32 1217  %2 = load i32, ptr %second.i, align 4218  %second2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 1219  %3 = load i32, ptr %second2.i, align 4220  %cmp2.i = icmp eq i32 %2, %3221  br i1 %cmp2.i, label %land.rhs.i.2, label %opeq1.exit222 223land.rhs.i.2:224  %third.i = getelementptr inbounds %S, ptr %a, i64 0, i32 2225  %4 = load i32, ptr %third.i, align 4226  %third2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 2227  %5 = load i32, ptr %third2.i, align 4228  %cmp3.i = icmp eq i32 %4, %5229  br i1 %cmp3.i, label %land.rhs.i.3, label %opeq1.exit230 231land.rhs.i.3:232  %fourth.i = getelementptr inbounds %S, ptr %a, i64 0, i32 3233  %6 = load i32, ptr %fourth.i, align 4234  %fourth2.i = getelementptr inbounds %S, ptr %b, i64 0, i32 3235  %7 = load i32, ptr %fourth2.i, align 4236  %cmp4.i = icmp eq i32 %6, %7237  br label %opeq1.exit238 239opeq1.exit:240  %8 = phi i1 [ false, %entry ], [ false, %land.rhs.i] , [ false, %land.rhs.i.2 ], [ %cmp4.i, %land.rhs.i.3 ]241  ret i1 %8242}243