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