1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that calls to memcmp with counts in excess of the array sizes are 3; either folded gracefully or expanded to library calls. 4; 5; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=BE 6; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=LE 7 8declare i32 @memcmp(i8*, i8*, i64) 9 10@ia16a = constant [4 x i16] [i16 24930, i16 25444, i16 25958, i16 26472] 11@ia16b = constant [5 x i16] [i16 24930, i16 25444, i16 25958, i16 26472, i16 26992] 12@ia16c = constant [6 x i16] [i16 24930, i16 25444, i16 25958, i16 26472, i16 26993, i16 29042] 13 14 15; Fold calls with a count in excess of the size of one of the arrays that 16; differ. They're strictly undefined but folding the result to the expected 17; value (analogous to strncmp) is safer than letting a SIMD library 18; implementation return a bogus value. 19 20define void @fold_memcmp_too_big(i32* %pcmp) { 21; BE-LABEL: @fold_memcmp_too_big( 22; BE-NEXT: [[CMP_BC:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(12) bitcast ([5 x i16]* @ia16b to i8*), i8* noundef nonnull dereferenceable(12) bitcast ([6 x i16]* @ia16c to i8*), i64 12) 23; BE-NEXT: store i32 [[CMP_BC]], i32* [[PCMP:%.*]], align 4 24; BE-NEXT: [[CMP_CB:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(12) bitcast ([6 x i16]* @ia16c to i8*), i8* noundef nonnull dereferenceable(12) bitcast ([5 x i16]* @ia16b to i8*), i64 12) 25; BE-NEXT: [[PSTOR_CB:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 26; BE-NEXT: store i32 [[CMP_CB]], i32* [[PSTOR_CB]], align 4 27; BE-NEXT: ret void 28; 29; LE-LABEL: @fold_memcmp_too_big( 30; LE-NEXT: [[CMP_BC:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(12) bitcast ([5 x i16]* @ia16b to i8*), i8* noundef nonnull dereferenceable(12) bitcast ([6 x i16]* @ia16c to i8*), i64 12) 31; LE-NEXT: store i32 [[CMP_BC]], i32* [[PCMP:%.*]], align 4 32; LE-NEXT: [[CMP_CB:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(12) bitcast ([6 x i16]* @ia16c to i8*), i8* noundef nonnull dereferenceable(12) bitcast ([5 x i16]* @ia16b to i8*), i64 12) 33; LE-NEXT: [[PSTOR_CB:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 34; LE-NEXT: store i32 [[CMP_CB]], i32* [[PSTOR_CB]], align 4 35; LE-NEXT: ret void 36; 37 %p0 = getelementptr [5 x i16], [5 x i16]* @ia16b, i64 0, i64 0 38 %p1 = bitcast i16* %p0 to i8* 39 %q0 = getelementptr [6 x i16], [6 x i16]* @ia16c, i64 0, i64 0 40 %q1 = bitcast i16* %q0 to i8* 41 42 %cmp_bc = call i32 @memcmp(i8* %p1, i8* %q1, i64 12) 43 %pstor_bc = getelementptr i32, i32* %pcmp, i64 0 44 store i32 %cmp_bc, i32* %pstor_bc 45 46 %cmp_cb = call i32 @memcmp(i8* %q1, i8* %p1, i64 12) 47 %pstor_cb = getelementptr i32, i32* %pcmp, i64 1 48 store i32 %cmp_cb, i32* %pstor_cb 49 50 ret void 51} 52 53 54; Don't fold calls with excessive byte counts of arrays with the same bytes. 55 56define void @call_memcmp_too_big(i32* %pcmp) { 57; BE-LABEL: @call_memcmp_too_big( 58; BE-NEXT: [[CMP_AB_9:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(9) bitcast ([4 x i16]* @ia16a to i8*), i8* noundef nonnull dereferenceable(9) bitcast ([5 x i16]* @ia16b to i8*), i64 9) 59; BE-NEXT: store i32 [[CMP_AB_9]], i32* [[PCMP:%.*]], align 4 60; BE-NEXT: [[CMP_AB_M1:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(18446744073709551615) bitcast ([4 x i16]* @ia16a to i8*), i8* noundef nonnull dereferenceable(18446744073709551615) bitcast ([5 x i16]* @ia16b to i8*), i64 -1) 61; BE-NEXT: [[PSTOR_AB_M1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 62; BE-NEXT: store i32 [[CMP_AB_M1]], i32* [[PSTOR_AB_M1]], align 4 63; BE-NEXT: ret void 64; 65; LE-LABEL: @call_memcmp_too_big( 66; LE-NEXT: [[CMP_AB_9:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(9) bitcast ([4 x i16]* @ia16a to i8*), i8* noundef nonnull dereferenceable(9) bitcast ([5 x i16]* @ia16b to i8*), i64 9) 67; LE-NEXT: store i32 [[CMP_AB_9]], i32* [[PCMP:%.*]], align 4 68; LE-NEXT: [[CMP_AB_M1:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(18446744073709551615) bitcast ([4 x i16]* @ia16a to i8*), i8* noundef nonnull dereferenceable(18446744073709551615) bitcast ([5 x i16]* @ia16b to i8*), i64 -1) 69; LE-NEXT: [[PSTOR_AB_M1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 70; LE-NEXT: store i32 [[CMP_AB_M1]], i32* [[PSTOR_AB_M1]], align 4 71; LE-NEXT: ret void 72; 73 %p0 = getelementptr [4 x i16], [4 x i16]* @ia16a, i64 0, i64 0 74 %p1 = bitcast i16* %p0 to i8* 75 %q0 = getelementptr [5 x i16], [5 x i16]* @ia16b, i64 0, i64 0 76 %q1 = bitcast i16* %q0 to i8* 77 78 %cmp_ab_9 = call i32 @memcmp(i8* %p1, i8* %q1, i64 9) 79 %pstor_ab_9 = getelementptr i32, i32* %pcmp, i64 0 80 store i32 %cmp_ab_9, i32* %pstor_ab_9 81 82 %cmp_ab_m1 = call i32 @memcmp(i8* %p1, i8* %q1, i64 -1) 83 %pstor_ab_m1 = getelementptr i32, i32* %pcmp, i64 1 84 store i32 %cmp_ab_m1, i32* %pstor_ab_m1 85 86 ret void 87} 88