1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='require<phi-values>,gvn' -S < %s | FileCheck %s 3 4declare noalias ptr @malloc(i64) 5 6; Detecting that %s is fully redundant should let us detect that %w is partially 7; redundant. 8define void @fn1(ptr noalias %start, ptr %width, i32 %h) { 9; CHECK-LABEL: @fn1( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) 12; CHECK-NEXT: store ptr [[CALL]], ptr [[START:%.*]], align 8 13; CHECK-NEXT: br label [[PREHEADER:%.*]] 14; CHECK: preheader: 15; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H:%.*]] 16; CHECK-NEXT: br i1 [[CMP]], label [[PREHEADER_BODY_CRIT_EDGE:%.*]], label [[EXIT:%.*]] 17; CHECK: preheader.body_crit_edge: 18; CHECK-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH:%.*]], align 8 19; CHECK-NEXT: br label [[BODY:%.*]] 20; CHECK: body: 21; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], [[BODY]] ] 22; CHECK-NEXT: store i32 0, ptr [[CALL]], align 4 23; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 24; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]] 25; CHECK-NEXT: br i1 [[CMP3]], label [[BODY]], label [[PREHEADER]] 26; CHECK: exit: 27; CHECK-NEXT: ret void 28; 29entry: 30 %call = tail call noalias ptr @malloc(i64 1024) 31 store ptr %call, ptr %start, align 8 32 br label %preheader 33 34preheader: 35 %cmp = icmp slt i32 1, %h 36 br i1 %cmp, label %body, label %exit 37 38body: 39 %j = phi i32 [ 0, %preheader ], [ %j.next, %body ] 40 %s = load ptr, ptr %start, align 8 41 store i32 0, ptr %s, align 4 42 %j.next = add nuw nsw i32 %j, 1 43 %w = load i32, ptr %width, align 8 44 %cmp3 = icmp slt i32 %j.next, %w 45 br i1 %cmp3, label %body, label %preheader 46 47exit: 48 ret void 49} 50 51; %s is fully redundant but has more than one available value. Detecting that 52; %w is partially redundant requires alias analysis that can analyze those 53; values. 54define void @fn2(ptr noalias %start, ptr %width, i32 %h, i32 %arg) { 55; CHECK-LABEL: @fn2( 56; CHECK-NEXT: entry: 57; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 1024) 58; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[ARG:%.*]], 0 59; CHECK-NEXT: br i1 [[CMP1]], label [[IF:%.*]], label [[ELSE:%.*]] 60; CHECK: if: 61; CHECK-NEXT: store ptr [[CALL]], ptr [[START:%.*]], align 8 62; CHECK-NEXT: br label [[PREHEADER:%.*]] 63; CHECK: else: 64; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[CALL]], i32 [[ARG]] 65; CHECK-NEXT: store ptr [[GEP]], ptr [[START]], align 8 66; CHECK-NEXT: br label [[PREHEADER]] 67; CHECK: preheader: 68; CHECK-NEXT: [[S:%.*]] = phi ptr [ [[S]], [[BODY:%.*]] ], [ [[GEP]], [[ELSE]] ], [ [[CALL]], [[IF]] ] 69; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 1, [[H:%.*]] 70; CHECK-NEXT: br i1 [[CMP]], label [[PREHEADER_BODY_CRIT_EDGE:%.*]], label [[EXIT:%.*]] 71; CHECK: preheader.body_crit_edge: 72; CHECK-NEXT: [[W_PRE:%.*]] = load i32, ptr [[WIDTH:%.*]], align 8 73; CHECK-NEXT: br label [[BODY]] 74; CHECK: body: 75; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[PREHEADER_BODY_CRIT_EDGE]] ], [ [[J_NEXT:%.*]], [[BODY]] ] 76; CHECK-NEXT: store i32 0, ptr [[S]], align 4 77; CHECK-NEXT: [[J_NEXT]] = add nuw nsw i32 [[J]], 1 78; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[J_NEXT]], [[W_PRE]] 79; CHECK-NEXT: br i1 [[CMP3]], label [[BODY]], label [[PREHEADER]] 80; CHECK: exit: 81; CHECK-NEXT: ret void 82; 83entry: 84 %call = tail call noalias ptr @malloc(i64 1024) 85 %cmp1 = icmp slt i32 %arg, 0 86 br i1 %cmp1, label %if, label %else 87 88if: 89 store ptr %call, ptr %start, align 8 90 br label %preheader 91 92else: 93 %gep = getelementptr inbounds i32, ptr %call, i32 %arg 94 store ptr %gep, ptr %start, align 8 95 br label %preheader 96 97preheader: 98 %cmp = icmp slt i32 1, %h 99 br i1 %cmp, label %body, label %exit 100 101body: 102 %j = phi i32 [ 0, %preheader ], [ %j.next, %body ] 103 %s = load ptr, ptr %start, align 8 104 store i32 0, ptr %s, align 4 105 %j.next = add nuw nsw i32 %j, 1 106 %w = load i32, ptr %width, align 8 107 %cmp3 = icmp slt i32 %j.next, %w 108 br i1 %cmp3, label %body, label %preheader 109 110exit: 111 ret void 112} 113