1; RUN: opt < %s -passes=instcombine -S | FileCheck --match-full-lines %s 2 3; Test cases to make sure !annotation metadata is preserved, if possible. 4; Currently we fail to preserve !annotation metadata in many cases. 5 6; Make sure !annotation metadata is added to new instructions, if the source 7; instruction has !annotation metadata. 8define i1 @fold_to_new_instruction(i8* %a, i8* %b) { 9; CHECK-LABEL: define {{.+}} @fold_to_new_instruction({{.+}} 10; CHECK-NEXT: [[C:%.*]] = icmp uge i8* [[A:%.*]], [[B:%[a-z]*]], !annotation [[ANN:![0-9]+]] 11; CHECK-NEXT: ret i1 [[C]] 12; 13 %a.c = bitcast i8* %a to i32*, !annotation !0 14 %b.c = bitcast i8* %b to i32*, !annotation !0 15 %c = icmp uge i32* %a.c, %b.c, !annotation !0 16 ret i1 %c 17} 18 19; Make sure !annotation is not added to new instructions if the source 20; instruction does not have it (even if some folded operands do have 21; !annotation). 22define i1 @fold_to_new_instruction2(i8* %a, i8* %b) { 23; CHECK-LABEL: define {{.+}} @fold_to_new_instruction2({{.+}} 24; CHECK-NEXT: [[C:%.*]] = icmp uge i8* [[A:%.*]], [[B:%[a-z]+]] 25; CHECK-NEXT: ret i1 [[C]] 26; 27 %a.c = bitcast i8* %a to i32*, !annotation !0 28 %b.c = bitcast i8* %b to i32*, !annotation !0 29 %c = icmp uge i32* %a.c, %b.c 30 ret i1 %c 31} 32 33; Make sure !annotation metadata is *not* added if we replace an instruction 34; with !annotation with an existing one without. 35define i32 @do_not_add_annotation_to_existing_instr(i32 %a, i32 %b) { 36; CHECK-LABEL: define {{.+}} @do_not_add_annotation_to_existing_instr({{.+}} 37; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A:%.*]], [[B:%[a-z]+]] 38; CHECK-NEXT: ret i32 [[ADD]] 39; 40 %add = add i32 %a, %b 41 %res = add i32 0, %add, !annotation !0 42 ret i32 %res 43} 44 45; memcpy can be expanded inline with load/store. Verify that we keep the 46; !annotation metadata. 47 48declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind 49 50define void @copy_1_byte(i8* %d, i8* %s) { 51; CHECK-LABEL: define {{.+}} @copy_1_byte({{.+}} 52; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[S:%.*]], align 1, !annotation [[ANN]] 53; CHECK-NEXT: store i8 [[TMP1]], i8* [[D:%.*]], align 1, !annotation [[ANN]] 54; CHECK-NEXT: ret void 55; 56 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %d, i8* %s, i32 1, i1 false), !annotation !0 57 ret void 58} 59 60declare i8* @memcpy(i8* noalias returned, i8* noalias nocapture readonly, i64) nofree nounwind 61 62define void @libcallcopy_1_byte(i8* %d, i8* %s) { 63; CHECK-LABEL: define {{.+}} @libcallcopy_1_byte({{.+}} 64; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[S:%.*]], align 1, !annotation [[ANN]] 65; CHECK-NEXT: store i8 [[TMP1]], i8* [[D:%.*]], align 1, !annotation [[ANN]] 66; CHECK-NEXT: ret void 67; 68 call i8* @memcpy(i8* %d, i8* %s, i64 1), !annotation !0 69 ret void 70} 71 72declare i8* @__memcpy_chk(i8*, i8*, i64, i64) nofree nounwind 73 74define void @libcallcopy_1_byte_chk(i8* %d, i8* %s) { 75; CHECK-LABEL: define {{.+}} @libcallcopy_1_byte_chk({{.+}} 76; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[S:%.*]], align 1, !annotation [[ANN]] 77; CHECK-NEXT: store i8 [[TMP1]], i8* [[D:%.*]], align 1, !annotation [[ANN]] 78; CHECK-NEXT: ret void 79; 80 call i8* @__memcpy_chk(i8* %d, i8* %s, i64 1, i64 1), !annotation !0 81 ret void 82} 83 84declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i1) nounwind 85 86define void @move_1_byte(i8* %d, i8* %s) { 87; CHECK-LABEL: define {{.+}} @move_1_byte({{.+}} 88; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[S:%.*]], align 1, !annotation [[ANN]] 89; CHECK-NEXT: store i8 [[TMP1]], i8* [[D:%.*]], align 1, !annotation [[ANN]] 90; CHECK-NEXT: ret void 91; 92 call void @llvm.memmove.p0i8.p0i8.i32(i8* %d, i8* %s, i32 1, i1 false), !annotation !0 93 ret void 94} 95 96declare i8* @memmove(i8* returned, i8* nocapture readonly, i64) nofree nounwind 97 98define void @libcallmove_1_byte(i8* %d, i8* %s) { 99; CHECK-LABEL: define {{.+}} @libcallmove_1_byte({{.+}} 100; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[S:%.*]], align 1, !annotation [[ANN]] 101; CHECK-NEXT: store i8 [[TMP1]], i8* [[D:%.*]], align 1, !annotation [[ANN]] 102; CHECK-NEXT: ret void 103; 104 call i8* @memmove(i8* %d, i8* %s, i64 1), !annotation !0 105 ret void 106} 107 108declare i8* @__memmove_chk(i8*, i8*, i64, i64) nofree nounwind 109 110define void @libcallmove_1_byte_chk(i8* %d, i8* %s) { 111; CHECK-LABEL: define {{.+}} @libcallmove_1_byte_chk({{.+}} 112; CHECK-NEXT: [[TMP1:%.*]] = load i8, i8* [[S:%.*]], align 1, !annotation [[ANN]] 113; CHECK-NEXT: store i8 [[TMP1]], i8* [[D:%.*]], align 1, !annotation [[ANN]] 114; CHECK-NEXT: ret void 115; 116 call i8* @__memmove_chk(i8* %d, i8* %s, i64 1, i64 1), !annotation !0 117 ret void 118} 119 120declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1) argmemonly nounwind 121 122define void @set_1_byte(i8* %d) { 123; CHECK-LABEL: define {{.+}} @set_1_byte({{.+}} 124; CHECK-NEXT: store i8 1, i8* [[D:%.*]], align 1, !annotation [[ANN]] 125; CHECK-NEXT: ret void 126; 127 call void @llvm.memset.p0i8.i32(i8* %d, i8 1, i32 1, i1 false), !annotation !0 128 ret void 129} 130 131declare i8* @memset(i8*, i32, i64) nofree 132 133define void @libcall_set_1_byte(i8* %d) { 134; CHECK-LABEL: define {{.+}} @libcall_set_1_byte({{.+}} 135; CHECK-NEXT: store i8 1, i8* [[D:%.*]], align 1, !annotation [[ANN]] 136; CHECK-NEXT: ret void 137; 138 call i8* @memset(i8* %d, i32 1, i64 1), !annotation !0 139 ret void 140} 141 142declare i8* @__memset_chk(i8*, i32, i64, i64) nofree 143 144define void @libcall_set_1_byte_chk(i8* %d) { 145; CHECK-LABEL: define {{.+}} @libcall_set_1_byte_chk({{.+}} 146; CHECK-NEXT: store i8 1, i8* [[D:%.*]], align 1, !annotation [[ANN]] 147; CHECK-NEXT: ret void 148; 149 call i8* @__memset_chk(i8* %d, i32 1, i64 1, i64 1), !annotation !0 150 ret void 151} 152 153!0 = !{ !"auto-init" } 154