[llvm] r182920 - [SystemZ] Enable unaligned accesses

Richard Sandiford rsandifo at linux.vnet.ibm.com
Thu May 30 02:45:42 PDT 2013


Author: rsandifo
Date: Thu May 30 04:45:42 2013
New Revision: 182920

URL: http://llvm.org/viewvc/llvm-project?rev=182920&view=rev
Log:
[SystemZ] Enable unaligned accesses

The code to distinguish between unaligned and aligned addresses was
already there, so this is mostly just a switch-on-and-test process.

Added:
    llvm/trunk/test/CodeGen/SystemZ/unaligned-01.ll
Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
    llvm/trunk/test/CodeGen/SystemZ/alloca-02.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-36.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-37.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-38.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-39.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-40.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-41.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-42.ll
    llvm/trunk/test/CodeGen/SystemZ/int-cmp-43.ll
    llvm/trunk/test/CodeGen/SystemZ/int-move-08.ll
    llvm/trunk/test/CodeGen/SystemZ/int-move-09.ll

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Thu May 30 04:45:42 2013
@@ -253,6 +253,16 @@ bool SystemZTargetLowering::isFPImmLegal
   return Imm.isZero() || Imm.isNegZero();
 }
 
+bool SystemZTargetLowering::allowsUnalignedMemoryAccesses(EVT VT,
+                                                          bool *Fast) const {
+  // Unaligned accesses should never be slower than the expanded version.
+  // We check specifically for aligned accesses in the few cases where
+  // they are required.
+  if (Fast)
+    *Fast = true;
+  return true;
+}
+  
 //===----------------------------------------------------------------------===//
 // Inline asm support
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h Thu May 30 04:45:42 2013
@@ -125,6 +125,7 @@ public:
     return true;
   }
   virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
+  virtual bool allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const;
   virtual const char *getTargetNodeName(unsigned Opcode) const LLVM_OVERRIDE;
   virtual std::pair<unsigned, const TargetRegisterClass *>
     getRegForInlineAsmConstraint(const std::string &Constraint,

Modified: llvm/trunk/test/CodeGen/SystemZ/alloca-02.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/alloca-02.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/alloca-02.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/alloca-02.ll Thu May 30 04:45:42 2013
@@ -34,15 +34,15 @@ define i64 @f1(i64 %length, i64 %index)
 ; CHECK-E: la [[TMP:%r[1-5]]], 160(%r3,[[ADDR]])
 ; CHECK-E: mviy 4096([[TMP]]), 4
   %a = alloca i8, i64 %length
-  store i8 0, i8 *%a
+  store volatile i8 0, i8 *%a
   %b = getelementptr i8 *%a, i64 4095
-  store i8 1, i8 *%b
+  store volatile i8 1, i8 *%b
   %c = getelementptr i8 *%a, i64 %index
-  store i8 2, i8 *%c
+  store volatile i8 2, i8 *%c
   %d = getelementptr i8 *%c, i64 4095
-  store i8 3, i8 *%d
+  store volatile i8 3, i8 *%d
   %e = getelementptr i8 *%d, i64 1
-  store i8 4, i8 *%e
+  store volatile i8 4, i8 *%e
   %count = call i64 @bar(i8 *%a)
   %res = add i64 %count, 1
   ret i64 %res

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-36.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-36.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-36.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-36.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i16 1
+ at h = global i16 1, align 1, section "foo"
 
 ; Check signed comparison.
 define i32 @f1(i32 %src1) {
@@ -74,6 +75,26 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i32 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i32 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i32 @f5(i32 %src1) {
+; CHECK: f5:
+; CHECK: lgrl [[REG:%r[0-5]]], h at GOT
+; CHECK: ch %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %val = load i16 *@h, align 1
+  %src2 = sext i16 %val to i32
+  %cond = icmp slt i32 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i32 %src1, %src1
   br label %exit
 exit:
   %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-37.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-37.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-37.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-37.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i16 1
+ at h = global i16 1, align 1, section "foo"
 
 ; Check unsigned comparison.
 define i32 @f1(i32 %src1) {
@@ -74,6 +75,27 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i32 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i32 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i32 @f5(i32 %src1) {
+; CHECK: f5:
+; CHECK: lgrl [[REG:%r[0-5]]], h at GOT
+; CHECK: llh [[VAL:%r[0-5]]], 0([[REG]])
+; CHECK: clr %r2, [[VAL]]
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %val = load i16 *@h, align 1
+  %src2 = zext i16 %val to i32
+  %cond = icmp ult i32 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i32 %src1, %src1
   br label %exit
 exit:
   %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-38.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-38.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-38.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-38.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i32 1
+ at h = global i32 1, align 2, section "foo"
 
 ; Check signed comparisons.
 define i32 @f1(i32 %src1) {
@@ -71,6 +72,44 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i32 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i32 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i32 @f5(i32 %src1) {
+; CHECK: f5:
+; CHECK: larl [[REG:%r[0-5]]], h
+; CHECK: c %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %src2 = load i32 *@h, align 2
+  %cond = icmp slt i32 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i32 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i32 %res
+}
+
+; Repeat f2 with an unaligned address.
+define i32 @f6(i32 %src1) {
+; CHECK: f6:
+; CHECK: larl [[REG:%r[0-5]]], h
+; CHECK: cl %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %src2 = load i32 *@h, align 2
+  %cond = icmp ult i32 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i32 %src1, %src1
   br label %exit
 exit:
   %res = phi i32 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-39.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-39.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-39.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-39.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i16 1
+ at h = global i16 1, align 1, section "foo"
 
 ; Check signed comparison.
 define i64 @f1(i64 %src1) {
@@ -74,6 +75,26 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i64 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i64 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i64 @f5(i64 %src1) {
+; CHECK: f5:
+; CHECK: lgrl [[REG:%r[0-5]]], h at GOT
+; CHECK: cgh %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %val = load i16 *@h, align 1
+  %src2 = sext i16 %val to i64
+  %cond = icmp slt i64 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i64 %src1, %src1
   br label %exit
 exit:
   %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-40.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-40.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-40.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-40.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i16 1
+ at h = global i16 1, align 1, section "foo"
 
 ; Check unsigned comparison.
 define i64 @f1(i64 %src1) {
@@ -74,6 +75,27 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i64 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i64 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i64 @f5(i64 %src1) {
+; CHECK: f5:
+; CHECK: lgrl [[REG:%r[0-5]]], h at GOT
+; CHECK: llgh [[VAL:%r[0-5]]], 0([[REG]])
+; CHECK: clgr %r2, [[VAL]]
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %val = load i16 *@h, align 1
+  %src2 = zext i16 %val to i64
+  %cond = icmp ult i64 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i64 %src1, %src1
   br label %exit
 exit:
   %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-41.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-41.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-41.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-41.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i32 1
+ at h = global i32 1, align 2, section "foo"
 
 ; Check signed comparison.
 define i64 @f1(i64 %src1) {
@@ -74,6 +75,26 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i64 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i64 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i64 @f5(i64 %src1) {
+; CHECK: f5:
+; CHECK: larl [[REG:%r[0-5]]], h
+; CHECK: cgf %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %val = load i32 *@h, align 2
+  %src2 = sext i32 %val to i64
+  %cond = icmp slt i64 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i64 %src1, %src1
   br label %exit
 exit:
   %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-42.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-42.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-42.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-42.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i32 1
+ at h = global i32 1, align 2, section "foo"
 
 ; Check unsigned comparison.
 define i64 @f1(i64 %src1) {
@@ -74,6 +75,26 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i64 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i64 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i64 @f5(i64 %src1) {
+; CHECK: f5:
+; CHECK: larl [[REG:%r[0-5]]], h
+; CHECK: clgf %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %val = load i32 *@h, align 2
+  %src2 = zext i32 %val to i64
+  %cond = icmp ult i64 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i64 %src1, %src1
   br label %exit
 exit:
   %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-cmp-43.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-cmp-43.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-cmp-43.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-cmp-43.ll Thu May 30 04:45:42 2013
@@ -4,6 +4,7 @@
 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
 
 @g = global i64 1
+ at h = global i64 1, align 4, section "foo"
 
 ; Check signed comparisons.
 define i64 @f1(i64 %src1) {
@@ -71,6 +72,25 @@ entry:
   br i1 %cond, label %exit, label %mulb
 mulb:
   %mul = mul i64 %src1, %src1
+  br label %exit
+exit:
+  %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]
+  ret i64 %res
+}
+
+; Repeat f1 with an unaligned address.
+define i64 @f5(i64 %src1) {
+; CHECK: f5:
+; CHECK: larl [[REG:%r[0-5]]], h
+; CHECK: cg %r2, 0([[REG]])
+; CHECK-NEXT: jl
+; CHECK: br %r14
+entry:
+  %src2 = load i64 *@h, align 4
+  %cond = icmp slt i64 %src1, %src2
+  br i1 %cond, label %exit, label %mulb
+mulb:
+  %mul = mul i64 %src1, %src1
   br label %exit
 exit:
   %res = phi i64 [ %src1, %entry ], [ %mul, %mulb ]

Modified: llvm/trunk/test/CodeGen/SystemZ/int-move-08.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-move-08.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-move-08.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-move-08.ll Thu May 30 04:45:42 2013
@@ -6,6 +6,10 @@
 @gsrc32 = global i32 1
 @gdst16 = global i16 2
 @gdst32 = global i32 2
+ at gsrc16u = global i16 1, align 1, section "foo"
+ at gsrc32u = global i32 1, align 2, section "foo"
+ at gdst16u = global i16 2, align 1, section "foo"
+ at gdst32u = global i32 2, align 2, section "foo"
 
 ; Check sign-extending loads from i16.
 define i32 @f1() {
@@ -47,3 +51,49 @@ define void @f4() {
   store i32 %val, i32 *@gdst32
   ret void
 }
+
+; Repeat f1 with an unaligned variable.
+define i32 @f5() {
+; CHECK: f5:
+; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u
+; CHECK: lh %r2, 0([[REG]])
+; CHECK: br %r14
+  %val = load i16 *@gsrc16u, align 1
+  %ext = sext i16 %val to i32
+  ret i32 %ext
+}
+
+; Repeat f2 with an unaligned variable.
+define i32 @f6() {
+; CHECK: f6:
+; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u
+; CHECK: llh %r2, 0([[REG]])
+; CHECK: br %r14
+  %val = load i16 *@gsrc16u, align 1
+  %ext = zext i16 %val to i32
+  ret i32 %ext
+}
+
+; Repeat f3 with an unaligned variable.
+define void @f7(i32 %val) {
+; CHECK: f7:
+; CHECK: lgrl [[REG:%r[0-5]]], gdst16u
+; CHECK: sth %r2, 0([[REG]])
+; CHECK: br %r14
+  %half = trunc i32 %val to i16
+  store i16 %half, i16 *@gdst16u, align 1
+  ret void
+}
+
+; Repeat f4 with unaligned variables.
+define void @f8() {
+; CHECK: f8:
+; CHECK: larl [[REG:%r[0-5]]], gsrc32u
+; CHECK: l [[VAL:%r[0-5]]], 0([[REG]])
+; CHECK: larl [[REG:%r[0-5]]], gdst32u
+; CHECK: st [[VAL]], 0([[REG]])
+; CHECK: br %r14
+  %val = load i32 *@gsrc32u, align 2
+  store i32 %val, i32 *@gdst32u, align 2
+  ret void
+}

Modified: llvm/trunk/test/CodeGen/SystemZ/int-move-09.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/int-move-09.ll?rev=182920&r1=182919&r2=182920&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/int-move-09.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/int-move-09.ll Thu May 30 04:45:42 2013
@@ -8,6 +8,12 @@
 @gdst16 = global i16 2
 @gdst32 = global i32 2
 @gdst64 = global i64 2
+ at gsrc16u = global i16 1, align 1, section "foo"
+ at gsrc32u = global i32 1, align 2, section "foo"
+ at gsrc64u = global i64 1, align 4, section "foo"
+ at gdst16u = global i16 2, align 1, section "foo"
+ at gdst32u = global i32 2, align 2, section "foo"
+ at gdst64u = global i64 2, align 4, section "foo"
 
 ; Check sign-extending loads from i16.
 define i64 @f1() {
@@ -79,3 +85,82 @@ define void @f7() {
   store i64 %val, i64 *@gdst64
   ret void
 }
+
+; Repeat f1 with an unaligned variable.
+define i64 @f8() {
+; CHECK: f8:
+; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u at GOT
+; CHECK: lgh %r2, 0([[REG]])
+; CHECK: br %r14
+  %val = load i16 *@gsrc16u, align 1
+  %ext = sext i16 %val to i64
+  ret i64 %ext
+}
+
+; Repeat f2 with an unaligned variable.
+define i64 @f9() {
+; CHECK: f9:
+; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u at GOT
+; CHECK: llgh %r2, 0([[REG]])
+; CHECK: br %r14
+  %val = load i16 *@gsrc16u, align 1
+  %ext = zext i16 %val to i64
+  ret i64 %ext
+}
+
+; Repeat f3 with an unaligned variable.
+define i64 @f10() {
+; CHECK: f10:
+; CHECK: larl [[REG:%r[0-5]]], gsrc32u
+; CHECK: lgf %r2, 0([[REG]])
+; CHECK: br %r14
+  %val = load i32 *@gsrc32u, align 2
+  %ext = sext i32 %val to i64
+  ret i64 %ext
+}
+
+; Repeat f4 with an unaligned variable.
+define i64 @f11() {
+; CHECK: f11:
+; CHECK: larl [[REG:%r[0-5]]], gsrc32u
+; CHECK: llgf %r2, 0([[REG]])
+; CHECK: br %r14
+  %val = load i32 *@gsrc32u, align 2
+  %ext = zext i32 %val to i64
+  ret i64 %ext
+}
+
+; Repeat f5 with an unaligned variable.
+define void @f12(i64 %val) {
+; CHECK: f12:
+; CHECK: lgrl [[REG:%r[0-5]]], gdst16u at GOT
+; CHECK: sth %r2, 0([[REG]])
+; CHECK: br %r14
+  %half = trunc i64 %val to i16
+  store i16 %half, i16 *@gdst16u, align 1
+  ret void
+}
+
+; Repeat f6 with an unaligned variable.
+define void @f13(i64 %val) {
+; CHECK: f13:
+; CHECK: larl [[REG:%r[0-5]]], gdst32u
+; CHECK: st %r2, 0([[REG]])
+; CHECK: br %r14
+  %word = trunc i64 %val to i32
+  store i32 %word, i32 *@gdst32u, align 2
+  ret void
+}
+
+; Repeat f7 with unaligned variables.
+define void @f14() {
+; CHECK: f14:
+; CHECK: larl [[REG:%r[0-5]]], gsrc64u
+; CHECK: lg [[VAL:%r[0-5]]], 0([[REG]])
+; CHECK: larl [[REG:%r[0-5]]], gdst64u
+; CHECK: stg [[VAL]], 0([[REG]])
+; CHECK: br %r14
+  %val = load i64 *@gsrc64u, align 4
+  store i64 %val, i64 *@gdst64u, align 4
+  ret void
+}

Added: llvm/trunk/test/CodeGen/SystemZ/unaligned-01.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/unaligned-01.ll?rev=182920&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/unaligned-01.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/unaligned-01.ll Thu May 30 04:45:42 2013
@@ -0,0 +1,59 @@
+; Check that unaligned accesses are allowed in general.  We check the
+; few exceptions (like CRL) in their respective test files.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+; Check that these four byte stores become a single word store.
+define void @f1(i8 *%ptr) {
+; CHECK: f1
+; CHECK: iilf [[REG:%r[0-5]]], 66051
+; CHECK: st [[REG]], 0(%r2)
+; CHECK: br %r14
+  %off1 = getelementptr i8 *%ptr, i64 1
+  %off2 = getelementptr i8 *%ptr, i64 2
+  %off3 = getelementptr i8 *%ptr, i64 3
+  store i8 0, i8 *%ptr
+  store i8 1, i8 *%off1
+  store i8 2, i8 *%off2
+  store i8 3, i8 *%off3
+  ret void
+}
+
+; Check that unaligned 2-byte accesses are allowed.
+define i16 @f2(i16 *%src, i16 *%dst) {
+; CHECK: f2:
+; CHECK: lh %r2, 0(%r2)
+; CHECK: sth %r2, 0(%r3)
+; CHECK: br %r14
+  %val = load i16 *%src, align 1
+  store i16 %val, i16 *%dst, align 1
+  ret i16 %val
+}
+
+; Check that unaligned 4-byte accesses are allowed.
+define i32 @f3(i32 *%src1, i32 *%src2, i32 *%dst) {
+; CHECK: f3:
+; CHECK: l %r2, 0(%r2)
+; CHECK: s %r2, 0(%r3)
+; CHECK: st %r2, 0(%r4)
+; CHECK: br %r14
+  %val1 = load i32 *%src1, align 1
+  %val2 = load i32 *%src2, align 2
+  %sub = sub i32 %val1, %val2
+  store i32 %sub, i32 *%dst, align 1
+  ret i32 %sub
+}
+
+; Check that unaligned 8-byte accesses are allowed.
+define i64 @f4(i64 *%src1, i64 *%src2, i64 *%dst) {
+; CHECK: f4:
+; CHECK: lg %r2, 0(%r2)
+; CHECK: sg %r2, 0(%r3)
+; CHECK: stg %r2, 0(%r4)
+; CHECK: br %r14
+  %val1 = load i64 *%src1, align 1
+  %val2 = load i64 *%src2, align 2
+  %sub = sub i64 %val1, %val2
+  store i64 %sub, i64 *%dst, align 4
+  ret i64 %sub
+}





More information about the llvm-commits mailing list