1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that calls to memcmp with arrays of elements larger than char 3; are folded correctly. 4; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=BE 5; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=LE 6 7declare i32 @memcmp(i8*, i8*, i64) 8 9; BE representation: { 'a', 'b', 'c', ..., 'f', 'g', 'h' } 10; LE representation: { 'b', 'a', 'd', ..., 'e', 'h', 'g' } 11@ia16a = constant [4 x i16] [i16 24930, i16 25444, i16 25958, i16 26472] 12 13; Same as the BE representation above except ending in "gg". 14@i8a = constant [8 x i8] c"abcdefgg" 15 16; Fold memcmp(ia16a, i8a, N) for N in [0, 8]. 17 18define void @fold_memcmp_ia16a_i8a(i32* %pcmp) { 19; BE-LABEL: @fold_memcmp_ia16a_i8a( 20; BE-NEXT: store i32 0, i32* [[PCMP:%.*]], align 4 21; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 22; BE-NEXT: store i32 0, i32* [[PSTOR1]], align 4 23; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 24; BE-NEXT: store i32 0, i32* [[PSTOR2]], align 4 25; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 26; BE-NEXT: store i32 0, i32* [[PSTOR3]], align 4 27; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 28; BE-NEXT: store i32 0, i32* [[PSTOR4]], align 4 29; BE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 30; BE-NEXT: store i32 0, i32* [[PSTOR5]], align 4 31; BE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, i32* [[PCMP]], i64 6 32; BE-NEXT: store i32 0, i32* [[PSTOR6]], align 4 33; BE-NEXT: [[PSTOR7:%.*]] = getelementptr i32, i32* [[PCMP]], i64 7 34; BE-NEXT: store i32 0, i32* [[PSTOR7]], align 4 35; BE-NEXT: [[PSTOR8:%.*]] = getelementptr i32, i32* [[PCMP]], i64 8 36; BE-NEXT: store i32 1, i32* [[PSTOR8]], align 4 37; BE-NEXT: ret void 38; 39; LE-LABEL: @fold_memcmp_ia16a_i8a( 40; LE-NEXT: store i32 0, i32* [[PCMP:%.*]], align 4 41; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 42; LE-NEXT: store i32 1, i32* [[PSTOR1]], align 4 43; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 44; LE-NEXT: store i32 1, i32* [[PSTOR2]], align 4 45; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 46; LE-NEXT: store i32 1, i32* [[PSTOR3]], align 4 47; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 48; LE-NEXT: store i32 1, i32* [[PSTOR4]], align 4 49; LE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 50; LE-NEXT: store i32 1, i32* [[PSTOR5]], align 4 51; LE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, i32* [[PCMP]], i64 6 52; LE-NEXT: store i32 1, i32* [[PSTOR6]], align 4 53; LE-NEXT: [[PSTOR7:%.*]] = getelementptr i32, i32* [[PCMP]], i64 7 54; LE-NEXT: store i32 1, i32* [[PSTOR7]], align 4 55; LE-NEXT: [[PSTOR8:%.*]] = getelementptr i32, i32* [[PCMP]], i64 8 56; LE-NEXT: store i32 1, i32* [[PSTOR8]], align 4 57; LE-NEXT: ret void 58; 59 %p0 = getelementptr [4 x i16], [4 x i16]* @ia16a, i64 0, i64 0 60 %p1 = bitcast i16* %p0 to i8* 61 %q = getelementptr [8 x i8], [8 x i8]* @i8a, i64 0, i64 0 62 63 %cmp0 = call i32 @memcmp(i8* %p1, i8* %q, i64 0) 64 %pstor0 = getelementptr i32, i32* %pcmp, i64 0 65 store i32 %cmp0, i32* %pstor0 66 67 %cmp1 = call i32 @memcmp(i8* %p1, i8* %q, i64 1) 68 %pstor1 = getelementptr i32, i32* %pcmp, i64 1 69 store i32 %cmp1, i32* %pstor1 70 71 %cmp2 = call i32 @memcmp(i8* %p1, i8* %q, i64 2) 72 %pstor2 = getelementptr i32, i32* %pcmp, i64 2 73 store i32 %cmp2, i32* %pstor2 74 75 %cmp3 = call i32 @memcmp(i8* %p1, i8* %q, i64 3) 76 %pstor3 = getelementptr i32, i32* %pcmp, i64 3 77 store i32 %cmp3, i32* %pstor3 78 79 %cmp4 = call i32 @memcmp(i8* %p1, i8* %q, i64 4) 80 %pstor4 = getelementptr i32, i32* %pcmp, i64 4 81 store i32 %cmp4, i32* %pstor4 82 83 %cmp5 = call i32 @memcmp(i8* %p1, i8* %q, i64 5) 84 %pstor5 = getelementptr i32, i32* %pcmp, i64 5 85 store i32 %cmp5, i32* %pstor5 86 87 %cmp6 = call i32 @memcmp(i8* %p1, i8* %q, i64 6) 88 %pstor6 = getelementptr i32, i32* %pcmp, i64 6 89 store i32 %cmp6, i32* %pstor6 90 91 %cmp7 = call i32 @memcmp(i8* %p1, i8* %q, i64 7) 92 %pstor7 = getelementptr i32, i32* %pcmp, i64 7 93 store i32 %cmp7, i32* %pstor7 94 95 %cmp8 = call i32 @memcmp(i8* %p1, i8* %q, i64 8) 96 %pstor8 = getelementptr i32, i32* %pcmp, i64 8 97 store i32 %cmp8, i32* %pstor8 98 99 ret void 100} 101 102 103; Fold memcmp(ia16a + 1, i8a + 2, N) for N in [0, 6]. 104 105define void @fold_memcmp_ia16a_p1_i8a_p1(i32* %pcmp) { 106; BE-LABEL: @fold_memcmp_ia16a_p1_i8a_p1( 107; BE-NEXT: store i32 0, i32* [[PCMP:%.*]], align 4 108; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 109; BE-NEXT: store i32 1, i32* [[PSTOR1]], align 4 110; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 111; BE-NEXT: store i32 1, i32* [[PSTOR2]], align 4 112; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 113; BE-NEXT: store i32 1, i32* [[PSTOR3]], align 4 114; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 115; BE-NEXT: store i32 1, i32* [[PSTOR4]], align 4 116; BE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 117; BE-NEXT: store i32 1, i32* [[PSTOR5]], align 4 118; BE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, i32* [[PCMP]], i64 6 119; BE-NEXT: store i32 1, i32* [[PSTOR6]], align 4 120; BE-NEXT: ret void 121; 122; LE-LABEL: @fold_memcmp_ia16a_p1_i8a_p1( 123; LE-NEXT: store i32 0, i32* [[PCMP:%.*]], align 4 124; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 125; LE-NEXT: store i32 1, i32* [[PSTOR1]], align 4 126; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 127; LE-NEXT: store i32 1, i32* [[PSTOR2]], align 4 128; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 129; LE-NEXT: store i32 1, i32* [[PSTOR3]], align 4 130; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 131; LE-NEXT: store i32 1, i32* [[PSTOR4]], align 4 132; LE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 133; LE-NEXT: store i32 1, i32* [[PSTOR5]], align 4 134; LE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, i32* [[PCMP]], i64 6 135; LE-NEXT: store i32 1, i32* [[PSTOR6]], align 4 136; LE-NEXT: ret void 137; 138 %p0 = getelementptr [4 x i16], [4 x i16]* @ia16a, i64 0, i64 1 139 %p1 = bitcast i16* %p0 to i8* 140 %q = getelementptr [8 x i8], [8 x i8]* @i8a, i64 0, i64 1 141 142 %cmp0 = call i32 @memcmp(i8* %p1, i8* %q, i64 0) 143 %pstor0 = getelementptr i32, i32* %pcmp, i64 0 144 store i32 %cmp0, i32* %pstor0 145 146 %cmp1 = call i32 @memcmp(i8* %p1, i8* %q, i64 1) 147 %pstor1 = getelementptr i32, i32* %pcmp, i64 1 148 store i32 %cmp1, i32* %pstor1 149 150 %cmp2 = call i32 @memcmp(i8* %p1, i8* %q, i64 2) 151 %pstor2 = getelementptr i32, i32* %pcmp, i64 2 152 store i32 %cmp2, i32* %pstor2 153 154 %cmp3 = call i32 @memcmp(i8* %p1, i8* %q, i64 3) 155 %pstor3 = getelementptr i32, i32* %pcmp, i64 3 156 store i32 %cmp3, i32* %pstor3 157 158 %cmp4 = call i32 @memcmp(i8* %p1, i8* %q, i64 4) 159 %pstor4 = getelementptr i32, i32* %pcmp, i64 4 160 store i32 %cmp4, i32* %pstor4 161 162 %cmp5 = call i32 @memcmp(i8* %p1, i8* %q, i64 5) 163 %pstor5 = getelementptr i32, i32* %pcmp, i64 5 164 store i32 %cmp5, i32* %pstor5 165 166 %cmp6 = call i32 @memcmp(i8* %p1, i8* %q, i64 6) 167 %pstor6 = getelementptr i32, i32* %pcmp, i64 6 168 store i32 %cmp6, i32* %pstor6 169 170 ret void 171} 172