diff options
Diffstat (limited to 'test/CodeGen/SystemZ/insert-06.ll')
-rw-r--r-- | test/CodeGen/SystemZ/insert-06.ll | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/test/CodeGen/SystemZ/insert-06.ll b/test/CodeGen/SystemZ/insert-06.ll new file mode 100644 index 0000000..4a13ef4 --- /dev/null +++ b/test/CodeGen/SystemZ/insert-06.ll @@ -0,0 +1,167 @@ +; Test insertions of i32s into the low half of an i64. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +; Insertion of an i32 can be done using LR. +define i64 @f1(i64 %a, i32 %b) { +; CHECK: f1: +; CHECK-NOT: {{%r[23]}} +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %low = zext i32 %b to i64 + %high = and i64 %a, -4294967296 + %res = or i64 %high, %low + ret i64 %res +} + +; ... and again with the operands reversed. +define i64 @f2(i64 %a, i32 %b) { +; CHECK: f2: +; CHECK-NOT: {{%r[23]}} +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %low = zext i32 %b to i64 + %high = and i64 %a, -4294967296 + %res = or i64 %low, %high + ret i64 %res +} + +; Like f1, but with "in register" zero extension. +define i64 @f3(i64 %a, i64 %b) { +; CHECK: f3: +; CHECK-NOT: {{%r[23]}} +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %low = and i64 %b, 4294967295 + %high = and i64 %a, -4294967296 + %res = or i64 %high, %low + ret i64 %res +} + +; ... and again with the operands reversed. +define i64 @f4(i64 %a, i64 %b) { +; CHECK: f4: +; CHECK-NOT: {{%r[23]}} +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %low = and i64 %b, 4294967295 + %high = and i64 %a, -4294967296 + %res = or i64 %low, %high + ret i64 %res +} + +; Unary operations can be done directly into the low half. +define i64 @f5(i64 %a, i32 %b) { +; CHECK: f5: +; CHECK-NOT: {{%r[23]}} +; CHECK: lcr %r2, %r3 +; CHECK: br %r14 + %neg = sub i32 0, %b + %low = zext i32 %neg to i64 + %high = and i64 %a, -4294967296 + %res = or i64 %high, %low + ret i64 %res +} + +; ...likewise three-operand binary operations like RLL. +define i64 @f6(i64 %a, i32 %b) { +; CHECK: f6: +; CHECK-NOT: {{%r[23]}} +; CHECK: rll %r2, %r3, 1 +; CHECK: br %r14 + %parta = shl i32 %b, 1 + %partb = lshr i32 %b, 31 + %rot = or i32 %parta, %partb + %low = zext i32 %rot to i64 + %high = and i64 %a, -4294967296 + %res = or i64 %low, %high + ret i64 %res +} + +; Loads can be done directly into the low half. The range of L is checked +; in the move tests. +define i64 @f7(i64 %a, i32 *%src) { +; CHECK: f7: +; CHECK-NOT: {{%r[23]}} +; CHECK: l %r2, 0(%r3) +; CHECK: br %r14 + %b = load i32 *%src + %low = zext i32 %b to i64 + %high = and i64 %a, -4294967296 + %res = or i64 %high, %low + ret i64 %res +} + +; ...likewise extending loads. +define i64 @f8(i64 %a, i8 *%src) { +; CHECK: f8: +; CHECK-NOT: {{%r[23]}} +; CHECK: lb %r2, 0(%r3) +; CHECK: br %r14 + %byte = load i8 *%src + %b = sext i8 %byte to i32 + %low = zext i32 %b to i64 + %high = and i64 %a, -4294967296 + %res = or i64 %high, %low + ret i64 %res +} + +; Check a case like f1 in which there is no AND. We simply know from context +; that the upper half of one OR operand and the lower half of the other are +; both clear. +define i64 @f9(i64 %a, i32 %b) { +; CHECK: f9: +; CHECK: sllg %r2, %r2, 32 +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %shift = shl i64 %a, 32 + %low = zext i32 %b to i64 + %or = or i64 %shift, %low + ret i64 %or +} + +; ...and again with the operands reversed. +define i64 @f10(i64 %a, i32 %b) { +; CHECK: f10: +; CHECK: sllg %r2, %r2, 32 +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %shift = shl i64 %a, 32 + %low = zext i32 %b to i64 + %or = or i64 %low, %shift + ret i64 %or +} + +; Like f9, but with "in register" zero extension. +define i64 @f11(i64 %a, i64 %b) { +; CHECK: f11: +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %shift = shl i64 %a, 32 + %low = and i64 %b, 4294967295 + %or = or i64 %shift, %low + ret i64 %or +} + +; ...and again with the operands reversed. +define i64 @f12(i64 %a, i64 %b) { +; CHECK: f12: +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %shift = shl i64 %a, 32 + %low = and i64 %b, 4294967295 + %or = or i64 %low, %shift + ret i64 %or +} + +; Like f9, but for larger shifts than 32. +define i64 @f13(i64 %a, i32 %b) { +; CHECK: f13: +; CHECK: sllg %r2, %r2, 60 +; CHECK: lr %r2, %r3 +; CHECK: br %r14 + %shift = shl i64 %a, 60 + %low = zext i32 %b to i64 + %or = or i64 %shift, %low + ret i64 %or +} |