163 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes='require<phi-values>,gvn' -S < %s | FileCheck %s --check-prefixes=CHECK-MEMDEP3; RUN: opt -passes='require<phi-values>,gvn<memoryssa>' -S < %s | FileCheck %s --check-prefixes=CHECK-MEMSSA4 5declare noalias ptr @malloc(i64)6 7; Detecting that %s is fully redundant should let us detect that %w is partially8; redundant.9define void @fn1(ptr noalias %start, ptr %width, i32 %h) {10; CHECK-MEMDEP-LABEL: define void @fn1(11; CHECK-MEMDEP-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]]) {12; CHECK-MEMDEP-NEXT: [[ENTRY:.*:]]13; CHECK-MEMDEP-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024)14; CHECK-MEMDEP-NEXT: store ptr [[CALL]], ptr [[START]], align 815; CHECK-MEMDEP-NEXT: br label %[[PREHEADER:.*]]16; CHECK-MEMDEP: [[PREHEADER]]:17; CHECK-MEMDEP-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]]18; CHECK-MEMDEP-NEXT: br i1 [[CMP]], label %[[PREHEADER_BODY_CRIT_EDGE:.*]], label %[[EXIT:.*]]19; CHECK-MEMDEP: [[PREHEADER_BODY_CRIT_EDGE]]:20; CHECK-MEMDEP-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH]], align 821; CHECK-MEMDEP-NEXT: br label %[[BODY:.*]]22; CHECK-MEMDEP: [[BODY]]:23; CHECK-MEMDEP-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], %[[BODY]] ]24; CHECK-MEMDEP-NEXT: store i32 0, ptr [[CALL]], align 425; CHECK-MEMDEP-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 126; CHECK-MEMDEP-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]]27; CHECK-MEMDEP-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]]28; CHECK-MEMDEP: [[EXIT]]:29; CHECK-MEMDEP-NEXT: ret void30;31; CHECK-MEMSSA-LABEL: define void @fn1(32; CHECK-MEMSSA-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]]) {33; CHECK-MEMSSA-NEXT: [[ENTRY:.*:]]34; CHECK-MEMSSA-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024)35; CHECK-MEMSSA-NEXT: store ptr [[CALL]], ptr [[START]], align 836; CHECK-MEMSSA-NEXT: br label %[[PREHEADER:.*]]37; CHECK-MEMSSA: [[PREHEADER]]:38; CHECK-MEMSSA-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]]39; CHECK-MEMSSA-NEXT: br i1 [[CMP]], label %[[BODY:.*]], label %[[EXIT:.*]]40; CHECK-MEMSSA: [[BODY]]:41; CHECK-MEMSSA-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER]] ], [ [[J_NEXT:%.*]], %[[BODY]] ]42; CHECK-MEMSSA-NEXT: [[S:%.*]] = load ptr, ptr [[START]], align 843; CHECK-MEMSSA-NEXT: store i32 0, ptr [[S]], align 444; CHECK-MEMSSA-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 145; CHECK-MEMSSA-NEXT: [[W:%.*]] = load i32, ptr [[WIDTH]], align 846; CHECK-MEMSSA-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W]]47; CHECK-MEMSSA-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]]48; CHECK-MEMSSA: [[EXIT]]:49; CHECK-MEMSSA-NEXT: ret void50;51entry:52 %call = tail call noalias ptr @malloc(i64 1024)53 store ptr %call, ptr %start, align 854 br label %preheader55 56preheader:57 %cmp = icmp slt i32 1, %h58 br i1 %cmp, label %body, label %exit59 60body:61 %j = phi i32 [ 0, %preheader ], [ %j.next, %body ]62 %s = load ptr, ptr %start, align 863 store i32 0, ptr %s, align 464 %j.next = add nuw nsw i32 %j, 165 %w = load i32, ptr %width, align 866 %cmp3 = icmp slt i32 %j.next, %w67 br i1 %cmp3, label %body, label %preheader68 69exit:70 ret void71}72 73; %s is fully redundant but has more than one available value. Detecting that74; %w is partially redundant requires alias analysis that can analyze those75; values.76define void @fn2(ptr noalias %start, ptr %width, i32 %h, i32 %arg) {77; CHECK-MEMDEP-LABEL: define void @fn2(78; CHECK-MEMDEP-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]], i32 [[ARG:%.*]]) {79; CHECK-MEMDEP-NEXT: [[ENTRY:.*:]]80; CHECK-MEMDEP-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024)81; CHECK-MEMDEP-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ARG]], 082; CHECK-MEMDEP-NEXT: br i1 [[CMP1]], label %[[IF:.*]], label %[[ELSE:.*]]83; CHECK-MEMDEP: [[IF]]:84; CHECK-MEMDEP-NEXT: store ptr [[CALL]], ptr [[START]], align 885; CHECK-MEMDEP-NEXT: br label %[[PREHEADER:.*]]86; CHECK-MEMDEP: [[ELSE]]:87; CHECK-MEMDEP-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i32 [[ARG]]88; CHECK-MEMDEP-NEXT: store ptr [[GEP]], ptr [[START]], align 889; CHECK-MEMDEP-NEXT: br label %[[PREHEADER]]90; CHECK-MEMDEP: [[PREHEADER]]:91; CHECK-MEMDEP-NEXT: [[S:%.*]] = phi ptr [ [[S]], %[[BODY:.*]] ], [ [[GEP]], %[[ELSE]] ], [ [[CALL]], %[[IF]] ]92; CHECK-MEMDEP-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]]93; CHECK-MEMDEP-NEXT: br i1 [[CMP]], label %[[PREHEADER_BODY_CRIT_EDGE:.*]], label %[[EXIT:.*]]94; CHECK-MEMDEP: [[PREHEADER_BODY_CRIT_EDGE]]:95; CHECK-MEMDEP-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH]], align 896; CHECK-MEMDEP-NEXT: br label %[[BODY]]97; CHECK-MEMDEP: [[BODY]]:98; CHECK-MEMDEP-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], %[[BODY]] ]99; CHECK-MEMDEP-NEXT: store i32 0, ptr [[S]], align 4100; CHECK-MEMDEP-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1101; CHECK-MEMDEP-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]]102; CHECK-MEMDEP-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]]103; CHECK-MEMDEP: [[EXIT]]:104; CHECK-MEMDEP-NEXT: ret void105;106; CHECK-MEMSSA-LABEL: define void @fn2(107; CHECK-MEMSSA-SAME: ptr noalias [[START:%.*]], ptr [[WIDTH:%.*]], i32 [[H:%.*]], i32 [[ARG:%.*]]) {108; CHECK-MEMSSA-NEXT: [[ENTRY:.*:]]109; CHECK-MEMSSA-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024)110; CHECK-MEMSSA-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ARG]], 0111; CHECK-MEMSSA-NEXT: br i1 [[CMP1]], label %[[IF:.*]], label %[[ELSE:.*]]112; CHECK-MEMSSA: [[IF]]:113; CHECK-MEMSSA-NEXT: store ptr [[CALL]], ptr [[START]], align 8114; CHECK-MEMSSA-NEXT: br label %[[PREHEADER:.*]]115; CHECK-MEMSSA: [[ELSE]]:116; CHECK-MEMSSA-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i32 [[ARG]]117; CHECK-MEMSSA-NEXT: store ptr [[GEP]], ptr [[START]], align 8118; CHECK-MEMSSA-NEXT: br label %[[PREHEADER]]119; CHECK-MEMSSA: [[PREHEADER]]:120; CHECK-MEMSSA-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H]]121; CHECK-MEMSSA-NEXT: br i1 [[CMP]], label %[[BODY:.*]], label %[[EXIT:.*]]122; CHECK-MEMSSA: [[BODY]]:123; CHECK-MEMSSA-NEXT: [[J:%.*]] = phi i32 [ 0, %[[PREHEADER]] ], [ [[J_NEXT:%.*]], %[[BODY]] ]124; CHECK-MEMSSA-NEXT: [[S:%.*]] = load ptr, ptr [[START]], align 8125; CHECK-MEMSSA-NEXT: store i32 0, ptr [[S]], align 4126; CHECK-MEMSSA-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1127; CHECK-MEMSSA-NEXT: [[W:%.*]] = load i32, ptr [[WIDTH]], align 8128; CHECK-MEMSSA-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W]]129; CHECK-MEMSSA-NEXT: br i1 [[CMP3]], label %[[BODY]], label %[[PREHEADER]]130; CHECK-MEMSSA: [[EXIT]]:131; CHECK-MEMSSA-NEXT: ret void132;133entry:134 %call = tail call noalias ptr @malloc(i64 1024)135 %cmp1 = icmp slt i32 %arg, 0136 br i1 %cmp1, label %if, label %else137 138if:139 store ptr %call, ptr %start, align 8140 br label %preheader141 142else:143 %gep = getelementptr inbounds i32, ptr %call, i32 %arg144 store ptr %gep, ptr %start, align 8145 br label %preheader146 147preheader:148 %cmp = icmp slt i32 1, %h149 br i1 %cmp, label %body, label %exit150 151body:152 %j = phi i32 [ 0, %preheader ], [ %j.next, %body ]153 %s = load ptr, ptr %start, align 8154 store i32 0, ptr %s, align 4155 %j.next = add nuw nsw i32 %j, 1156 %w = load i32, ptr %width, align 8157 %cmp3 = icmp slt i32 %j.next, %w158 br i1 %cmp3, label %body, label %preheader159 160exit:161 ret void162}163