231 lines · plain
1; Test insertions of memory into the low byte of an i32.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5; Check a plain insertion with (or (and ... -0xff) (zext (load ....))).6; The whole sequence can be performed by IC.7define i32 @f1(i32 %orig, ptr %ptr) {8; CHECK-LABEL: f1:9; CHECK-NOT: ni10; CHECK: ic %r2, 0(%r3)11; CHECK: br %r1412 %val = load i8, ptr %ptr13 %ptr2 = zext i8 %val to i3214 %ptr1 = and i32 %orig, -25615 %or = or i32 %ptr1, %ptr216 ret i32 %or17}18 19; Like f1, but with the operands reversed.20define i32 @f2(i32 %orig, ptr %ptr) {21; CHECK-LABEL: f2:22; CHECK-NOT: ni23; CHECK: ic %r2, 0(%r3)24; CHECK: br %r1425 %val = load i8, ptr %ptr26 %ptr2 = zext i8 %val to i3227 %ptr1 = and i32 %orig, -25628 %or = or i32 %ptr2, %ptr129 ret i32 %or30}31 32; Check a case where more bits than lower 8 are masked out of the33; register value. We can use IC but must keep the original mask.34define i32 @f3(i32 %orig, ptr %ptr) {35; CHECK-LABEL: f3:36; CHECK: nill %r2, 6502437; CHECK: ic %r2, 0(%r3)38; CHECK: br %r1439 %val = load i8, ptr %ptr40 %ptr2 = zext i8 %val to i3241 %ptr1 = and i32 %orig, -51242 %or = or i32 %ptr1, %ptr243 ret i32 %or44}45 46; Like f3, but with the operands reversed.47define i32 @f4(i32 %orig, ptr %ptr) {48; CHECK-LABEL: f4:49; CHECK: nill %r2, 6502450; CHECK: ic %r2, 0(%r3)51; CHECK: br %r1452 %val = load i8, ptr %ptr53 %ptr2 = zext i8 %val to i3254 %ptr1 = and i32 %orig, -51255 %or = or i32 %ptr2, %ptr156 ret i32 %or57}58 59; Check a case where the low 8 bits are cleared by a shift left.60define i32 @f5(i32 %orig, ptr %ptr) {61; CHECK-LABEL: f5:62; CHECK: sll %r2, 863; CHECK: ic %r2, 0(%r3)64; CHECK: br %r1465 %val = load i8, ptr %ptr66 %ptr2 = zext i8 %val to i3267 %ptr1 = shl i32 %orig, 868 %or = or i32 %ptr1, %ptr269 ret i32 %or70}71 72; Like f5, but with the operands reversed.73define i32 @f6(i32 %orig, ptr %ptr) {74; CHECK-LABEL: f6:75; CHECK: sll %r2, 876; CHECK: ic %r2, 0(%r3)77; CHECK: br %r1478 %val = load i8, ptr %ptr79 %ptr2 = zext i8 %val to i3280 %ptr1 = shl i32 %orig, 881 %or = or i32 %ptr2, %ptr182 ret i32 %or83}84 85; Check insertions into a constant.86define i32 @f7(i32 %orig, ptr %ptr) {87; CHECK-LABEL: f7:88; CHECK: lhi %r2, 25689; CHECK: ic %r2, 0(%r3)90; CHECK: br %r1491 %val = load i8, ptr %ptr92 %ptr2 = zext i8 %val to i3293 %or = or i32 %ptr2, 25694 ret i32 %or95}96 97; Like f7, but with the operands reversed.98define i32 @f8(i32 %orig, ptr %ptr) {99; CHECK-LABEL: f8:100; CHECK: lhi %r2, 256101; CHECK: ic %r2, 0(%r3)102; CHECK: br %r14103 %val = load i8, ptr %ptr104 %ptr2 = zext i8 %val to i32105 %or = or i32 256, %ptr2106 ret i32 %or107}108 109; Check the high end of the IC range.110define i32 @f9(i32 %orig, ptr %src) {111; CHECK-LABEL: f9:112; CHECK: ic %r2, 4095(%r3)113; CHECK: br %r14114 %ptr = getelementptr i8, ptr %src, i64 4095115 %val = load i8, ptr %ptr116 %src2 = zext i8 %val to i32117 %src1 = and i32 %orig, -256118 %or = or i32 %src2, %src1119 ret i32 %or120}121 122; Check the next byte up, which should use ICY instead of IC.123define i32 @f10(i32 %orig, ptr %src) {124; CHECK-LABEL: f10:125; CHECK: icy %r2, 4096(%r3)126; CHECK: br %r14127 %ptr = getelementptr i8, ptr %src, i64 4096128 %val = load i8, ptr %ptr129 %src2 = zext i8 %val to i32130 %src1 = and i32 %orig, -256131 %or = or i32 %src2, %src1132 ret i32 %or133}134 135; Check the high end of the ICY range.136define i32 @f11(i32 %orig, ptr %src) {137; CHECK-LABEL: f11:138; CHECK: icy %r2, 524287(%r3)139; CHECK: br %r14140 %ptr = getelementptr i8, ptr %src, i64 524287141 %val = load i8, ptr %ptr142 %src2 = zext i8 %val to i32143 %src1 = and i32 %orig, -256144 %or = or i32 %src2, %src1145 ret i32 %or146}147 148; Check the next byte up, which needs separate address logic.149; Other sequences besides this one would be OK.150define i32 @f12(i32 %orig, ptr %src) {151; CHECK-LABEL: f12:152; CHECK: agfi %r3, 524288153; CHECK: ic %r2, 0(%r3)154; CHECK: br %r14155 %ptr = getelementptr i8, ptr %src, i64 524288156 %val = load i8, ptr %ptr157 %src2 = zext i8 %val to i32158 %src1 = and i32 %orig, -256159 %or = or i32 %src2, %src1160 ret i32 %or161}162 163; Check the high end of the negative ICY range.164define i32 @f13(i32 %orig, ptr %src) {165; CHECK-LABEL: f13:166; CHECK: icy %r2, -1(%r3)167; CHECK: br %r14168 %ptr = getelementptr i8, ptr %src, i64 -1169 %val = load i8, ptr %ptr170 %src2 = zext i8 %val to i32171 %src1 = and i32 %orig, -256172 %or = or i32 %src2, %src1173 ret i32 %or174}175 176; Check the low end of the ICY range.177define i32 @f14(i32 %orig, ptr %src) {178; CHECK-LABEL: f14:179; CHECK: icy %r2, -524288(%r3)180; CHECK: br %r14181 %ptr = getelementptr i8, ptr %src, i64 -524288182 %val = load i8, ptr %ptr183 %src2 = zext i8 %val to i32184 %src1 = and i32 %orig, -256185 %or = or i32 %src2, %src1186 ret i32 %or187}188 189; Check the next byte down, which needs separate address logic.190; Other sequences besides this one would be OK.191define i32 @f15(i32 %orig, ptr %src) {192; CHECK-LABEL: f15:193; CHECK: agfi %r3, -524289194; CHECK: ic %r2, 0(%r3)195; CHECK: br %r14196 %ptr = getelementptr i8, ptr %src, i64 -524289197 %val = load i8, ptr %ptr198 %src2 = zext i8 %val to i32199 %src1 = and i32 %orig, -256200 %or = or i32 %src2, %src1201 ret i32 %or202}203 204; Check that IC allows an index.205define i32 @f16(i32 %orig, ptr %src, i64 %index) {206; CHECK-LABEL: f16:207; CHECK: ic %r2, 4095({{%r4,%r3|%r3,%r4}})208; CHECK: br %r14209 %ptr1 = getelementptr i8, ptr %src, i64 %index210 %ptr2 = getelementptr i8, ptr %ptr1, i64 4095211 %val = load i8, ptr %ptr2212 %src2 = zext i8 %val to i32213 %src1 = and i32 %orig, -256214 %or = or i32 %src2, %src1215 ret i32 %or216}217 218; Check that ICY allows an index.219define i32 @f17(i32 %orig, ptr %src, i64 %index) {220; CHECK-LABEL: f17:221; CHECK: icy %r2, 4096({{%r4,%r3|%r3,%r4}})222; CHECK: br %r14223 %ptr1 = getelementptr i8, ptr %src, i64 %index224 %ptr2 = getelementptr i8, ptr %ptr1, i64 4096225 %val = load i8, ptr %ptr2226 %src2 = zext i8 %val to i32227 %src1 = and i32 %orig, -256228 %or = or i32 %src2, %src1229 ret i32 %or230}231