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