150 lines · plain
1; RUN: opt < %s -passes=instcombine -S | FileCheck --match-full-lines %s2 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 source7; 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 !014 ret i1 %c15}16 17; Make sure !annotation is not added to new instructions if the source18; instruction does not have it (even if some folded operands do have19; !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, %b26 ret i1 %c27}28 29; Make sure !annotation metadata is *not* added if we replace an instruction30; 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, %b37 %res = add i32 0, %add, !annotation !038 ret i32 %res39}40 41; memcpy can be expanded inline with load/store. Verify that we keep the42; !annotation metadata.43 44declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind45 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 void51;52 call void @llvm.memcpy.p0.p0.i32(ptr %d, ptr %s, i32 1, i1 false), !annotation !053 ret void54}55 56declare ptr @memcpy(ptr noalias returned, ptr noalias nocapture readonly, i64) nofree nounwind57 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 void63;64 call ptr @memcpy(ptr %d, ptr %s, i64 1), !annotation !065 ret void66}67 68declare ptr @__memcpy_chk(ptr, ptr, i64, i64) nofree nounwind69 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 void75;76 call ptr @__memcpy_chk(ptr %d, ptr %s, i64 1, i64 1), !annotation !077 ret void78}79 80declare void @llvm.memmove.p0.p0.i32(ptr nocapture, ptr nocapture readonly, i32, i1) nounwind81 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 void87;88 call void @llvm.memmove.p0.p0.i32(ptr %d, ptr %s, i32 1, i1 false), !annotation !089 ret void90}91 92declare ptr @memmove(ptr returned, ptr nocapture readonly, i64) nofree nounwind93 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 void99;100 call ptr @memmove(ptr %d, ptr %s, i64 1), !annotation !0101 ret void102}103 104declare ptr @__memmove_chk(ptr, ptr, i64, i64) nofree nounwind105 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 void111;112 call ptr @__memmove_chk(ptr %d, ptr %s, i64 1, i64 1), !annotation !0113 ret void114}115 116declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1) argmemonly nounwind117 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 void122;123 call void @llvm.memset.p0.i32(ptr %d, i8 1, i32 1, i1 false), !annotation !0124 ret void125}126 127declare ptr @memset(ptr, i32, i64) nofree128 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 void133;134 call ptr @memset(ptr %d, i32 1, i64 1), !annotation !0135 ret void136}137 138declare ptr @__memset_chk(ptr, i32, i64, i64) nofree139 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 void144;145 call ptr @__memset_chk(ptr %d, i32 1, i64 1, i64 1), !annotation !0146 ret void147}148 149!0 = !{ !"auto-init" }150