[llvm] r286126 - [MemCpyOpt] Don't emit IR in an unspecified order

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 7 09:47:28 PST 2016


Author: d0k
Date: Mon Nov  7 11:47:28 2016
New Revision: 286126

URL: http://llvm.org/viewvc/llvm-project?rev=286126&view=rev
Log:
[MemCpyOpt] Don't emit IR in an unspecified order

Argument evaluation order is one of the edge cases where Clang differs
from GCC, yielding different IR depending on which compiler LLVM was
built with. Make the order deterministic and tune the test to actually
verify the order instead of trying to hide it.

Modified:
    llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
    llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll

Modified: llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp?rev=286126&r1=286125&r2=286126&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/MemCpyOptimizer.cpp Mon Nov  7 11:47:28 2016
@@ -1080,10 +1080,10 @@ bool MemCpyOptPass::processMemSetMemCpyD
       DestSize = Builder.CreateZExt(DestSize, SrcSize->getType());
   }
 
-  Value *MemsetLen =
-      Builder.CreateSelect(Builder.CreateICmpULE(DestSize, SrcSize),
-                           ConstantInt::getNullValue(DestSize->getType()),
-                           Builder.CreateSub(DestSize, SrcSize));
+  Value *Ule = Builder.CreateICmpULE(DestSize, SrcSize);
+  Value *SizeDiff = Builder.CreateSub(DestSize, SrcSize);
+  Value *MemsetLen = Builder.CreateSelect(
+      Ule, ConstantInt::getNullValue(DestSize->getType()), SizeDiff);
   Builder.CreateMemSet(Builder.CreateGEP(Dest, SrcSize), MemSet->getOperand(1),
                        MemsetLen, Align);
 

Modified: llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll?rev=286126&r1=286125&r2=286126&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll (original)
+++ llvm/trunk/test/Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll Mon Nov  7 11:47:28 2016
@@ -3,10 +3,10 @@
 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
 
 ; CHECK-LABEL: define void @test
-; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
-; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, %src_size
-; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, %src_size
-; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, %src_size
+; CHECK: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, %src_size
+; CHECK: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
 ; CHECK-NEXT: ret void
@@ -17,11 +17,11 @@ define void @test(i8* %src, i64 %src_siz
 }
 
 ; CHECK-LABEL: define void @test_different_types_i32_i64
-; CHECK-DAG: [[DSTSIZE:%[0-9]+]] = zext i32 %dst_size to i64
-; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
-; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 [[DSTSIZE]], %src_size
-; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 [[DSTSIZE]], %src_size
-; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[DSTSIZE:%[0-9]+]] = zext i32 %dst_size to i64
+; CHECK: [[ULE:%[0-9]+]] = icmp ule i64 [[DSTSIZE]], %src_size
+; CHECK: [[SIZEDIFF:%[0-9]+]] = sub i64 [[DSTSIZE]], %src_size
+; CHECK: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
 ; CHECK-NEXT: ret void
@@ -32,11 +32,11 @@ define void @test_different_types_i32_i6
 }
 
 ; CHECK-LABEL: define void @test_different_types_i128_i32
-; CHECK-DAG: [[SRCSIZE:%[0-9]+]] = zext i32 %src_size to i128
-; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i128 [[SRCSIZE]]
-; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i128 %dst_size, [[SRCSIZE]]
-; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i128 %dst_size, [[SRCSIZE]]
-; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i128 0, i128 [[SIZEDIFF]]
+; CHECK: [[SRCSIZE:%[0-9]+]] = zext i32 %src_size to i128
+; CHECK: [[ULE:%[0-9]+]] = icmp ule i128 %dst_size, [[SRCSIZE]]
+; CHECK: [[SIZEDIFF:%[0-9]+]] = sub i128 %dst_size, [[SRCSIZE]]
+; CHECK: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i128 0, i128 [[SIZEDIFF]]
+; CHECK: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i128 [[SRCSIZE]]
 ; CHECK-NEXT: call void @llvm.memset.p0i8.i128(i8* [[DST]], i8 %c, i128 [[SIZE]], i32 1, i1 false)
 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %src_size, i32 1, i1 false)
 ; CHECK-NEXT: ret void
@@ -47,11 +47,11 @@ define void @test_different_types_i128_i
 }
 
 ; CHECK-LABEL: define void @test_different_types_i32_i128
-; CHECK-DAG: [[DSTSIZE:%[0-9]+]] = zext i32 %dst_size to i128
-; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i128 %src_size
-; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i128 [[DSTSIZE]], %src_size
-; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i128 [[DSTSIZE]], %src_size
-; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i128 0, i128 [[SIZEDIFF]]
+; CHECK: [[DSTSIZE:%[0-9]+]] = zext i32 %dst_size to i128
+; CHECK: [[ULE:%[0-9]+]] = icmp ule i128 [[DSTSIZE]], %src_size
+; CHECK: [[SIZEDIFF:%[0-9]+]] = sub i128 [[DSTSIZE]], %src_size
+; CHECK: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i128 0, i128 [[SIZEDIFF]]
+; CHECK: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i128 %src_size
 ; CHECK-NEXT: call void @llvm.memset.p0i8.i128(i8* [[DST]], i8 %c, i128 [[SIZE]], i32 1, i1 false)
 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i128(i8* %dst, i8* %src, i128 %src_size, i32 1, i1 false)
 ; CHECK-NEXT: ret void
@@ -62,11 +62,11 @@ define void @test_different_types_i32_i1
 }
 
 ; CHECK-LABEL: define void @test_different_types_i64_i32
-; CHECK-DAG: [[SRCSIZE:%[0-9]+]] = zext i32 %src_size to i64
-; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 [[SRCSIZE]]
-; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, [[SRCSIZE]]
-; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, [[SRCSIZE]]
-; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[SRCSIZE:%[0-9]+]] = zext i32 %src_size to i64
+; CHECK: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, [[SRCSIZE]]
+; CHECK: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, [[SRCSIZE]]
+; CHECK: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 [[SRCSIZE]]
 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src, i32 %src_size, i32 1, i1 false)
 ; CHECK-NEXT: ret void
@@ -102,10 +102,10 @@ define void @test_align_memcpy(i8* %src,
 
 ; CHECK-LABEL: define void @test_non_i8_dst_type
 ; CHECK-NEXT: %dst = bitcast i64* %dst_pi64 to i8*
-; CHECK-DAG: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
-; CHECK-DAG: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, %src_size
-; CHECK-DAG: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, %src_size
-; CHECK-DAG: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[ULE:%[0-9]+]] = icmp ule i64 %dst_size, %src_size
+; CHECK: [[SIZEDIFF:%[0-9]+]] = sub i64 %dst_size, %src_size
+; CHECK: [[SIZE:%[0-9]+]] = select i1 [[ULE]], i64 0, i64 [[SIZEDIFF]]
+; CHECK: [[DST:%[0-9]+]] = getelementptr i8, i8* %dst, i64 %src_size
 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DST]], i8 %c, i64 [[SIZE]], i32 1, i1 false)
 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %src_size, i32 1, i1 false)
 ; CHECK-NEXT: ret void




More information about the llvm-commits mailing list