[opaque pointer type] Add textual IR support for explicit type parameter to gep operator
[oota-llvm.git] / test / CodeGen / X86 / smul-with-overflow.ll
1 ; RUN: llc < %s -march=x86 | FileCheck %s
2
3 @ok = internal constant [4 x i8] c"%d\0A\00"
4 @no = internal constant [4 x i8] c"no\0A\00"
5
6 define i1 @test1(i32 %v1, i32 %v2) nounwind {
7 entry:
8   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
9   %sum = extractvalue {i32, i1} %t, 0
10   %obit = extractvalue {i32, i1} %t, 1
11   br i1 %obit, label %overflow, label %normal
12
13 normal:
14   %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8], [4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
15   ret i1 true
16
17 overflow:
18   %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8], [4 x i8]* @no, i32 0, i32 0) ) nounwind
19   ret i1 false
20 ; CHECK-LABEL: test1:
21 ; CHECK: imull
22 ; CHECK-NEXT: jno
23 }
24
25 define i1 @test2(i32 %v1, i32 %v2) nounwind {
26 entry:
27   %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
28   %sum = extractvalue {i32, i1} %t, 0
29   %obit = extractvalue {i32, i1} %t, 1
30   br i1 %obit, label %overflow, label %normal
31
32 overflow:
33   %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8], [4 x i8]* @no, i32 0, i32 0) ) nounwind
34   ret i1 false
35
36 normal:
37   %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8], [4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
38   ret i1 true
39 ; CHECK-LABEL: test2:
40 ; CHECK: imull
41 ; CHECK-NEXT: jno
42 }
43
44 declare i32 @printf(i8*, ...) nounwind
45 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
46
47 define i32 @test3(i32 %a, i32 %b) nounwind readnone {
48 entry:
49         %tmp0 = add i32 %b, %a
50         %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 2)
51         %tmp2 = extractvalue { i32, i1 } %tmp1, 0
52         ret i32 %tmp2
53 ; CHECK-LABEL: test3:
54 ; CHECK: addl
55 ; CHECK-NEXT: addl
56 ; CHECK-NEXT: ret
57 }
58
59 define i32 @test4(i32 %a, i32 %b) nounwind readnone {
60 entry:
61         %tmp0 = add i32 %b, %a
62         %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 4)
63         %tmp2 = extractvalue { i32, i1 } %tmp1, 0
64         ret i32 %tmp2
65 ; CHECK-LABEL: test4:
66 ; CHECK: addl
67 ; CHECK: mull
68 ; CHECK-NEXT: ret
69 }
70
71 declare { i63, i1 } @llvm.smul.with.overflow.i63(i63, i63) nounwind readnone
72
73 define i1 @test5() nounwind {
74 entry:
75   %res = call { i63, i1 } @llvm.smul.with.overflow.i63(i63 4, i63 4611686018427387903)
76   %sum = extractvalue { i63, i1 } %res, 0
77   %overflow = extractvalue { i63, i1 } %res, 1
78   ret i1 %overflow
79 ; Was returning false, should return true (not constant folded yet though).
80 ; PR13991
81 ; CHECK-LABEL: test5:
82 ; CHECK-NOT: xorb
83 }