| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; Verify that calls to memcmp with arrays of elements larger than char |
| ; are folded correctly. |
| ; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=BE |
| ; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=LE |
| |
| declare i32 @memcmp(ptr, ptr, i64) |
| |
| ; BE representation: { 'a', 'b', 'c', ..., 'f', 'g', 'h' } |
| ; LE representation: { 'b', 'a', 'd', ..., 'e', 'h', 'g' } |
| @ia16a = constant [4 x i16] [i16 24930, i16 25444, i16 25958, i16 26472] |
| |
| ; Same as the BE representation above except ending in "gg". |
| @i8a = constant [8 x i8] c"abcdefgg" |
| |
| ; Fold memcmp(ia16a, i8a, N) for N in [0, 8]. |
| |
| define void @fold_memcmp_ia16a_i8a(ptr %pcmp) { |
| ; BE-LABEL: @fold_memcmp_ia16a_i8a( |
| ; BE-NEXT: store i32 0, ptr [[PCMP:%.*]], align 4 |
| ; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR1]], align 4 |
| ; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR2]], align 4 |
| ; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR3]], align 4 |
| ; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR4]], align 4 |
| ; BE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR5]], align 4 |
| ; BE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, ptr [[PCMP]], i64 6 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR6]], align 4 |
| ; BE-NEXT: [[PSTOR7:%.*]] = getelementptr i32, ptr [[PCMP]], i64 7 |
| ; BE-NEXT: store i32 0, ptr [[PSTOR7]], align 4 |
| ; BE-NEXT: [[PSTOR8:%.*]] = getelementptr i32, ptr [[PCMP]], i64 8 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR8]], align 4 |
| ; BE-NEXT: ret void |
| ; |
| ; LE-LABEL: @fold_memcmp_ia16a_i8a( |
| ; LE-NEXT: store i32 0, ptr [[PCMP:%.*]], align 4 |
| ; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR1]], align 4 |
| ; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR2]], align 4 |
| ; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR3]], align 4 |
| ; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR4]], align 4 |
| ; LE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR5]], align 4 |
| ; LE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, ptr [[PCMP]], i64 6 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR6]], align 4 |
| ; LE-NEXT: [[PSTOR7:%.*]] = getelementptr i32, ptr [[PCMP]], i64 7 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR7]], align 4 |
| ; LE-NEXT: [[PSTOR8:%.*]] = getelementptr i32, ptr [[PCMP]], i64 8 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR8]], align 4 |
| ; LE-NEXT: ret void |
| ; |
| |
| %cmp0 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 0) |
| store i32 %cmp0, ptr %pcmp |
| |
| %cmp1 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 1) |
| %pstor1 = getelementptr i32, ptr %pcmp, i64 1 |
| store i32 %cmp1, ptr %pstor1 |
| |
| %cmp2 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 2) |
| %pstor2 = getelementptr i32, ptr %pcmp, i64 2 |
| store i32 %cmp2, ptr %pstor2 |
| |
| %cmp3 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 3) |
| %pstor3 = getelementptr i32, ptr %pcmp, i64 3 |
| store i32 %cmp3, ptr %pstor3 |
| |
| %cmp4 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 4) |
| %pstor4 = getelementptr i32, ptr %pcmp, i64 4 |
| store i32 %cmp4, ptr %pstor4 |
| |
| %cmp5 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 5) |
| %pstor5 = getelementptr i32, ptr %pcmp, i64 5 |
| store i32 %cmp5, ptr %pstor5 |
| |
| %cmp6 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 6) |
| %pstor6 = getelementptr i32, ptr %pcmp, i64 6 |
| store i32 %cmp6, ptr %pstor6 |
| |
| %cmp7 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 7) |
| %pstor7 = getelementptr i32, ptr %pcmp, i64 7 |
| store i32 %cmp7, ptr %pstor7 |
| |
| %cmp8 = call i32 @memcmp(ptr @ia16a, ptr @i8a, i64 8) |
| %pstor8 = getelementptr i32, ptr %pcmp, i64 8 |
| store i32 %cmp8, ptr %pstor8 |
| |
| ret void |
| } |
| |
| |
| ; Fold memcmp(ia16a + 1, i8a + 2, N) for N in [0, 6]. |
| |
| define void @fold_memcmp_ia16a_p1_i8a_p1(ptr %pcmp) { |
| ; BE-LABEL: @fold_memcmp_ia16a_p1_i8a_p1( |
| ; BE-NEXT: store i32 0, ptr [[PCMP:%.*]], align 4 |
| ; BE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR1]], align 4 |
| ; BE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR2]], align 4 |
| ; BE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR3]], align 4 |
| ; BE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR4]], align 4 |
| ; BE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR5]], align 4 |
| ; BE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, ptr [[PCMP]], i64 6 |
| ; BE-NEXT: store i32 1, ptr [[PSTOR6]], align 4 |
| ; BE-NEXT: ret void |
| ; |
| ; LE-LABEL: @fold_memcmp_ia16a_p1_i8a_p1( |
| ; LE-NEXT: store i32 0, ptr [[PCMP:%.*]], align 4 |
| ; LE-NEXT: [[PSTOR1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR1]], align 4 |
| ; LE-NEXT: [[PSTOR2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR2]], align 4 |
| ; LE-NEXT: [[PSTOR3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR3]], align 4 |
| ; LE-NEXT: [[PSTOR4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR4]], align 4 |
| ; LE-NEXT: [[PSTOR5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR5]], align 4 |
| ; LE-NEXT: [[PSTOR6:%.*]] = getelementptr i32, ptr [[PCMP]], i64 6 |
| ; LE-NEXT: store i32 1, ptr [[PSTOR6]], align 4 |
| ; LE-NEXT: ret void |
| ; |
| %p0 = getelementptr [4 x i16], ptr @ia16a, i64 0, i64 1 |
| %q = getelementptr [8 x i8], ptr @i8a, i64 0, i64 1 |
| |
| %cmp0 = call i32 @memcmp(ptr %p0, ptr %q, i64 0) |
| store i32 %cmp0, ptr %pcmp |
| |
| %cmp1 = call i32 @memcmp(ptr %p0, ptr %q, i64 1) |
| %pstor1 = getelementptr i32, ptr %pcmp, i64 1 |
| store i32 %cmp1, ptr %pstor1 |
| |
| %cmp2 = call i32 @memcmp(ptr %p0, ptr %q, i64 2) |
| %pstor2 = getelementptr i32, ptr %pcmp, i64 2 |
| store i32 %cmp2, ptr %pstor2 |
| |
| %cmp3 = call i32 @memcmp(ptr %p0, ptr %q, i64 3) |
| %pstor3 = getelementptr i32, ptr %pcmp, i64 3 |
| store i32 %cmp3, ptr %pstor3 |
| |
| %cmp4 = call i32 @memcmp(ptr %p0, ptr %q, i64 4) |
| %pstor4 = getelementptr i32, ptr %pcmp, i64 4 |
| store i32 %cmp4, ptr %pstor4 |
| |
| %cmp5 = call i32 @memcmp(ptr %p0, ptr %q, i64 5) |
| %pstor5 = getelementptr i32, ptr %pcmp, i64 5 |
| store i32 %cmp5, ptr %pstor5 |
| |
| %cmp6 = call i32 @memcmp(ptr %p0, ptr %q, i64 6) |
| %pstor6 = getelementptr i32, ptr %pcmp, i64 6 |
| store i32 %cmp6, ptr %pstor6 |
| |
| ret void |
| } |