brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · af1bc98 Raw
123 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes='function(gvn)' -S | FileCheck -check-prefixes=CHECK-GVN %s3 4; Also do some runs using an GVN+O1 pipeline, using O1 to clean up after GVN.5; This is to easier see the semantic of the resulting IR and that it hopefully6; is the same as if only running O1 directly.7;8; RUN: opt < %s -passes='function(gvn),default<O1>' -S | FileCheck -check-prefixes=CHECK-GVN-O1 %s9; RUN: opt < %s -passes='default<O1>' -S | FileCheck -check-prefixes=CHECK-O1 %s10 11; This is a reproducer for the miscompile reported here:12;   https://github.com/llvm/llvm-project/issues/5702513;14; Explanation of the test case:15;  - Outer loop will do three iterations i:=0, i:=1 and i:=216;  - When is i==0 the value 7 is stored to arr[0]17;  - When is i!=0 the value 42 is stored to arr[i]18;  - There is a nestled while loop reduced down to something just setting j:=i19;    and then exiting.20;  - In while.end arr[j] (i.e. the just stored to arr[i]) is loaded,21;    and the loaded value is passed to the verify function.22;  - There is a dead load of the not yet initialized arr[j+1] in the epilog23;    block. This might seem irrelevant, but is needed to reproduce the24;    miscompile.25;26; Expected semantic of the function is that verify() will be called three27; times, with the values 7, 42 and 42.28 29declare void @verify(i16)30 31define void @test(i16 %g) {32; CHECK-GVN-LABEL: @test(33; CHECK-GVN-NEXT:  entry:34; CHECK-GVN-NEXT:    [[ARR:%.*]] = alloca [4 x i16], align 135; CHECK-GVN-NEXT:    br label [[FOR_BODY:%.*]]36; CHECK-GVN:       for.body:37; CHECK-GVN-NEXT:    [[I:%.*]] = phi i16 [ 0, [[ENTRY:%.*]] ], [ [[NEXT_I:%.*]], [[WHILE_END:%.*]] ]38; CHECK-GVN-NEXT:    [[CMP0:%.*]] = icmp eq i16 [[I]], 039; CHECK-GVN-NEXT:    br i1 [[CMP0]], label [[STORE_IDX_0:%.*]], label [[STORE_IDX_I:%.*]]40; CHECK-GVN:       store.idx.0:41; CHECK-GVN-NEXT:    store i16 7, ptr [[ARR]], align 142; CHECK-GVN-NEXT:    br label [[STORE_DONE:%.*]]43; CHECK-GVN:       store.idx.i:44; CHECK-GVN-NEXT:    [[ARR_I:%.*]] = getelementptr [4 x i16], ptr [[ARR]], i16 0, i16 [[I]]45; CHECK-GVN-NEXT:    store i16 42, ptr [[ARR_I]], align 146; CHECK-GVN-NEXT:    br label [[STORE_DONE]]47; CHECK-GVN:       store.done:48; CHECK-GVN-NEXT:    br label [[WHILE_BODY:%.*]]49; CHECK-GVN:       while.body:50; CHECK-GVN-NEXT:    br i1 false, label [[WHILE_BODY_WHILE_BODY_CRIT_EDGE:%.*]], label [[WHILE_END]]51; CHECK-GVN:       while.body.while.body_crit_edge:52; CHECK-GVN-NEXT:    br label [[WHILE_BODY]]53; CHECK-GVN:       while.end:54; CHECK-GVN-NEXT:    [[ARR_J:%.*]] = getelementptr [4 x i16], ptr [[ARR]], i16 0, i16 [[I]]55; CHECK-GVN-NEXT:    [[VALUE:%.*]] = load i16, ptr [[ARR_J]], align 156; CHECK-GVN-NEXT:    tail call void @verify(i16 [[VALUE]])57; CHECK-GVN-NEXT:    [[NEXT_I]] = add i16 [[I]], 158; CHECK-GVN-NEXT:    [[ARR_NEXT_I:%.*]] = getelementptr [4 x i16], ptr [[ARR]], i16 0, i16 [[NEXT_I]]59; CHECK-GVN-NEXT:    [[CMP4:%.*]] = icmp slt i16 [[NEXT_I]], 360; CHECK-GVN-NEXT:    br i1 [[CMP4]], label [[FOR_BODY]], label [[FOR_END:%.*]]61; CHECK-GVN:       for.end:62; CHECK-GVN-NEXT:    ret void63;64; CHECK-GVN-O1-LABEL: @test(65; CHECK-GVN-O1-NEXT:  entry:66; CHECK-GVN-O1-NEXT:    tail call void @verify(i16 7)67; CHECK-GVN-O1-NEXT:    tail call void @verify(i16 42)68; CHECK-GVN-O1-NEXT:    tail call void @verify(i16 42)69; CHECK-GVN-O1-NEXT:    ret void70;71; CHECK-O1-LABEL: @test(72; CHECK-O1-NEXT:  entry:73; CHECK-O1-NEXT:    tail call void @verify(i16 7)74; CHECK-O1-NEXT:    tail call void @verify(i16 42)75; CHECK-O1-NEXT:    tail call void @verify(i16 42)76; CHECK-O1-NEXT:    ret void77;78entry:79  %arr = alloca [4 x i16], align 180  br label %for.body81 82for.body:                                         ; preds = %epilog, %entry83  %i = phi i16 [ 0, %entry ], [ %next.i, %epilog ]84  %cmp0 = icmp eq i16 %i, 085  br i1 %cmp0, label %store.idx.0, label %store.idx.i86 87store.idx.0:                                      ; preds = %for.body88  store i16 7, ptr %arr, align 189  br label %store.done90 91store.idx.i:                                      ; preds = %for.body92  %arr.i = getelementptr [4 x i16], ptr %arr, i16 0, i16 %i93  store i16 42, ptr %arr.i, align 194  br label %store.done95 96store.done:                                        ; preds = %store.idx.i, %store.idx.097  br label %while.body98 99while.body:                                       ; preds = %while.body, %store.done100  %j = phi i16 [ %i, %store.done ], [ 0, %while.body ]101  ; Constant foldable conditional branch.102  ; Needed to reproduce the fault!103  br i1 false, label %while.body, label %while.end104 105while.end:                                        ; preds = %while.body106  %arr.j = getelementptr [4 x i16], ptr %arr, i16 0, i16 %j107  %value = load i16, ptr %arr.j, align 1108  tail call void @verify(i16 %value)109  br label %epilog110 111epilog:                                          ; preds = %while.end112  %next.i = add i16 %j, 1113  %arr.next.i = getelementptr [4 x i16], ptr %arr, i16 0, i16 %next.i114  ; A dead load.115  ;  Needed to reproduce the fault!116  %dead = load i16, ptr %arr.next.i, align 1117  %cmp4 = icmp slt i16 %next.i, 3118  br i1 %cmp4, label %for.body, label %for.end119 120for.end:                                          ; preds = %epilog121  ret void122}123