1*9880d681SAndroid Build Coastguard Worker; Test that the memcmp library call simplifier works correctly. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32:64" 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker@foo = constant [4 x i8] c"foo\00" 8*9880d681SAndroid Build Coastguard Worker@hel = constant [4 x i8] c"hel\00" 9*9880d681SAndroid Build Coastguard Worker@hello_u = constant [8 x i8] c"hello_u\00" 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdeclare i32 @memcmp(i8*, i8*, i32) 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker; Check memcmp(mem, mem, size) -> 0. 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify1(i8* %mem, i32 %size) { 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify1( 17*9880d681SAndroid Build Coastguard Worker %ret = call i32 @memcmp(i8* %mem, i8* %mem, i32 %size) 18*9880d681SAndroid Build Coastguard Worker ret i32 %ret 19*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 20*9880d681SAndroid Build Coastguard Worker} 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; Check memcmp(mem1, mem2, 0) -> 0. 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify2(i8* %mem1, i8* %mem2) { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify2( 26*9880d681SAndroid Build Coastguard Worker %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 0) 27*9880d681SAndroid Build Coastguard Worker ret i32 %ret 28*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker;; Check memcmp(mem1, mem2, 1) -> *(unsigned char*)mem1 - *(unsigned char*)mem2. 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify3(i8* %mem1, i8* %mem2) { 34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify3( 35*9880d681SAndroid Build Coastguard Worker %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 1) 36*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOAD1:%[a-z]+]] = load i8, i8* %mem1, align 1 37*9880d681SAndroid Build Coastguard Worker; CHECK: [[ZEXT1:%[a-z]+]] = zext i8 [[LOAD1]] to i32 38*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOAD2:%[a-z]+]] = load i8, i8* %mem2, align 1 39*9880d681SAndroid Build Coastguard Worker; CHECK: [[ZEXT2:%[a-z]+]] = zext i8 [[LOAD2]] to i32 40*9880d681SAndroid Build Coastguard Worker; CHECK: [[RET:%[a-z]+]] = sub nsw i32 [[ZEXT1]], [[ZEXT2]] 41*9880d681SAndroid Build Coastguard Worker ret i32 %ret 42*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 [[RET]] 43*9880d681SAndroid Build Coastguard Worker} 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker; Check memcmp(mem1, mem2, size) -> cnst, where all arguments are constants. 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify4() { 48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify4( 49*9880d681SAndroid Build Coastguard Worker %mem1 = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0 50*9880d681SAndroid Build Coastguard Worker %mem2 = getelementptr [8 x i8], [8 x i8]* @hello_u, i32 0, i32 0 51*9880d681SAndroid Build Coastguard Worker %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3) 52*9880d681SAndroid Build Coastguard Worker ret i32 %ret 53*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 0 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify5() { 57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify5( 58*9880d681SAndroid Build Coastguard Worker %mem1 = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0 59*9880d681SAndroid Build Coastguard Worker %mem2 = getelementptr [4 x i8], [4 x i8]* @foo, i32 0, i32 0 60*9880d681SAndroid Build Coastguard Worker %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3) 61*9880d681SAndroid Build Coastguard Worker ret i32 %ret 62*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 1 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Workerdefine i32 @test_simplify6() { 66*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify6( 67*9880d681SAndroid Build Coastguard Worker %mem1 = getelementptr [4 x i8], [4 x i8]* @foo, i32 0, i32 0 68*9880d681SAndroid Build Coastguard Worker %mem2 = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0 69*9880d681SAndroid Build Coastguard Worker %ret = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 3) 70*9880d681SAndroid Build Coastguard Worker ret i32 %ret 71*9880d681SAndroid Build Coastguard Worker; CHECK: ret i32 -1 72*9880d681SAndroid Build Coastguard Worker} 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker; Check memcmp(mem1, mem2, 8)==0 -> *(int64_t*)mem1 == *(int64_t*)mem2 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Workerdefine i1 @test_simplify7(i64 %x, i64 %y) { 77*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify7( 78*9880d681SAndroid Build Coastguard Worker %x.addr = alloca i64, align 8 79*9880d681SAndroid Build Coastguard Worker %y.addr = alloca i64, align 8 80*9880d681SAndroid Build Coastguard Worker store i64 %x, i64* %x.addr, align 8 81*9880d681SAndroid Build Coastguard Worker store i64 %y, i64* %y.addr, align 8 82*9880d681SAndroid Build Coastguard Worker %xptr = bitcast i64* %x.addr to i8* 83*9880d681SAndroid Build Coastguard Worker %yptr = bitcast i64* %y.addr to i8* 84*9880d681SAndroid Build Coastguard Worker %call = call i32 @memcmp(i8* %xptr, i8* %yptr, i32 8) 85*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %call, 0 86*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 87*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp = icmp eq i64 %x, %y 88*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 %cmp 89*9880d681SAndroid Build Coastguard Worker} 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker; Check memcmp(mem1, mem2, 4)==0 -> *(int32_t*)mem1 == *(int32_t*)mem2 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Workerdefine i1 @test_simplify8(i32 %x, i32 %y) { 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify8( 95*9880d681SAndroid Build Coastguard Worker %x.addr = alloca i32, align 4 96*9880d681SAndroid Build Coastguard Worker %y.addr = alloca i32, align 4 97*9880d681SAndroid Build Coastguard Worker store i32 %x, i32* %x.addr, align 4 98*9880d681SAndroid Build Coastguard Worker store i32 %y, i32* %y.addr, align 4 99*9880d681SAndroid Build Coastguard Worker %xptr = bitcast i32* %x.addr to i8* 100*9880d681SAndroid Build Coastguard Worker %yptr = bitcast i32* %y.addr to i8* 101*9880d681SAndroid Build Coastguard Worker %call = call i32 @memcmp(i8* %xptr, i8* %yptr, i32 4) 102*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %call, 0 103*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 104*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp = icmp eq i32 %x, %y 105*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 %cmp 106*9880d681SAndroid Build Coastguard Worker} 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker; Check memcmp(mem1, mem2, 2)==0 -> *(int16_t*)mem1 == *(int16_t*)mem2 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerdefine i1 @test_simplify9(i16 %x, i16 %y) { 111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_simplify9( 112*9880d681SAndroid Build Coastguard Worker %x.addr = alloca i16, align 2 113*9880d681SAndroid Build Coastguard Worker %y.addr = alloca i16, align 2 114*9880d681SAndroid Build Coastguard Worker store i16 %x, i16* %x.addr, align 2 115*9880d681SAndroid Build Coastguard Worker store i16 %y, i16* %y.addr, align 2 116*9880d681SAndroid Build Coastguard Worker %xptr = bitcast i16* %x.addr to i8* 117*9880d681SAndroid Build Coastguard Worker %yptr = bitcast i16* %y.addr to i8* 118*9880d681SAndroid Build Coastguard Worker %call = call i32 @memcmp(i8* %xptr, i8* %yptr, i32 2) 119*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %call, 0 120*9880d681SAndroid Build Coastguard Worker ret i1 %cmp 121*9880d681SAndroid Build Coastguard Worker; CHECK: %cmp = icmp eq i16 %x, %y 122*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 %cmp 123*9880d681SAndroid Build Coastguard Worker} 124