[FastISel][X86] Emit more efficient instructions for integer constant materialization.

This mostly affects the i64 value type, which always resulted in an 15byte
mobavsq instruction to materialize any constant. The custom code checks the
value of the immediate and tries to use a different and smaller mov
instruction when possible.

This fixes <rdar://problem/17420988>.

llvm-svn: 215593
This commit is contained in:
Juergen Ributzka 2014-08-13 22:18:11 +00:00
parent b6ac3f93e7
commit 230494b399
3 changed files with 177 additions and 212 deletions

View File

@ -3105,7 +3105,34 @@ X86FastISel::TargetSelectInstruction(const Instruction *I) {
unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
if (VT > MVT::i64)
return 0;
return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
uint64_t Imm = CI->getZExtValue();
unsigned Opc = 0;
switch (VT.SimpleTy) {
default: llvm_unreachable("Unexpected value type");
case MVT::i1: VT = MVT::i8; // fall-through
case MVT::i8: Opc = X86::MOV8ri; break;
case MVT::i16: Opc = X86::MOV16ri; break;
case MVT::i32: Opc = X86::MOV32ri; break;
case MVT::i64: {
if (isUInt<32>(Imm))
Opc = X86::MOV32ri;
else if (isInt<32>(Imm))
Opc = X86::MOV64ri32;
else
Opc = X86::MOV64ri;
break;
}
}
if (VT == MVT::i64 && Opc == X86::MOV32ri) {
unsigned SrcReg = FastEmitInst_i(Opc, &X86::GR32RegClass, Imm);
unsigned ResultReg = createResultReg(&X86::GR64RegClass);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
.addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
return ResultReg;
}
return FastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
}
unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {

View File

@ -1,4 +1,4 @@
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s
; ModuleID = 'ts.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@ -12,8 +12,8 @@ entry:
%tmp = load i8** @p ; <i8*> [#uses=1]
%0 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp, i1 0) ; <i64> [#uses=1]
%cmp = icmp ne i64 %0, -1 ; <i1> [#uses=1]
; X64: movabsq $-1, [[RAX:%r..]]
; X64: cmpq $-1, [[RAX]]
; CHECK: movq $-1, [[RAX:%r..]]
; CHECK: cmpq $-1, [[RAX]]
br i1 %cmp, label %cond.true, label %cond.false
cond.true: ; preds = %entry

View File

@ -1,7 +1,5 @@
; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=DAG
; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s --check-prefix=FAST
; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s
; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s
; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG
; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
;
; Get the actual value of the overflow bit.
@ -9,12 +7,9 @@
; SADDO reg, reg
define zeroext i1 @saddo.i8(i8 signext %v1, i8 signext %v2, i8* %res) {
entry:
; DAG-LABEL: saddo.i8
; DAG: addb %sil, %dil
; DAG-NEXT: seto %al
; FAST-LABEL: saddo.i8
; FAST: addb %sil, %dil
; FAST-NEXT: seto %al
; CHECK-LABEL: saddo.i8
; CHECK: addb %sil, %dil
; CHECK-NEXT: seto %al
%t = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v1, i8 %v2)
%val = extractvalue {i8, i1} %t, 0
%obit = extractvalue {i8, i1} %t, 1
@ -24,12 +19,9 @@ entry:
define zeroext i1 @saddo.i16(i16 %v1, i16 %v2, i16* %res) {
entry:
; DAG-LABEL: saddo.i16
; DAG: addw %si, %di
; DAG-NEXT: seto %al
; FAST-LABEL: saddo.i16
; FAST: addw %si, %di
; FAST-NEXT: seto %al
; CHECK-LABEL: saddo.i16
; CHECK: addw %si, %di
; CHECK-NEXT: seto %al
%t = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %v1, i16 %v2)
%val = extractvalue {i16, i1} %t, 0
%obit = extractvalue {i16, i1} %t, 1
@ -39,12 +31,9 @@ entry:
define zeroext i1 @saddo.i32(i32 %v1, i32 %v2, i32* %res) {
entry:
; DAG-LABEL: saddo.i32
; DAG: addl %esi, %edi
; DAG-NEXT: seto %al
; FAST-LABEL: saddo.i32
; FAST: addl %esi, %edi
; FAST-NEXT: seto %al
; CHECK-LABEL: saddo.i32
; CHECK: addl %esi, %edi
; CHECK-NEXT: seto %al
%t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -54,12 +43,9 @@ entry:
define zeroext i1 @saddo.i64(i64 %v1, i64 %v2, i64* %res) {
entry:
; DAG-LABEL: saddo.i64
; DAG: addq %rsi, %rdi
; DAG-NEXT: seto %al
; FAST-LABEL: saddo.i64
; FAST: addq %rsi, %rdi
; FAST-NEXT: seto %al
; CHECK-LABEL: saddo.i64
; CHECK: addq %rsi, %rdi
; CHECK-NEXT: seto %al
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -120,13 +106,13 @@ entry:
; FIXME: DAG doesn't optimize immediates on the LHS.
define zeroext i1 @saddo.i64imm1(i64 %v1, i64* %res) {
entry:
; DAG-LABEL: saddo.i64imm1
; DAG: mov
; DAG-NEXT: addq
; DAG-NEXT: seto
; FAST-LABEL: saddo.i64imm1
; FAST: addq $2, %rdi
; FAST-NEXT: seto %al
; SDAG-LABEL: saddo.i64imm1
; SDAG: mov
; SDAG-NEXT: addq
; SDAG-NEXT: seto
; FAST-LABEL: saddo.i64imm1
; FAST: addq $2, %rdi
; FAST-NEXT: seto %al
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 2, i64 %v1)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -137,12 +123,12 @@ entry:
; Check boundary conditions for large immediates.
define zeroext i1 @saddo.i64imm2(i64 %v1, i64* %res) {
entry:
; DAG-LABEL: saddo.i64imm2
; DAG: addq $-2147483648, %rdi
; DAG-NEXT: seto %al
; FAST-LABEL: saddo.i64imm2
; FAST: addq $-2147483648, %rdi
; FAST-NEXT: seto %al
; SDAG-LABEL: saddo.i64imm2
; SDAG: addq $-2147483648, %rdi
; SDAG-NEXT: seto %al
; FAST-LABEL: saddo.i64imm2
; FAST: addq $-2147483648, %rdi
; FAST-NEXT: seto %al
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -2147483648)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -152,14 +138,10 @@ entry:
define zeroext i1 @saddo.i64imm3(i64 %v1, i64* %res) {
entry:
; DAG-LABEL: saddo.i64imm3
; DAG: movabsq $-21474836489, %[[REG:[a-z]+]]
; DAG-NEXT: addq %rdi, %[[REG]]
; DAG-NEXT: seto
; FAST-LABEL: saddo.i64imm3
; FAST: movabsq $-21474836489, %[[REG:[a-z]+]]
; FAST-NEXT: addq %rdi, %[[REG]]
; FAST-NEXT: seto
; CHECK-LABEL: saddo.i64imm3
; CHECK: movabsq $-21474836489, %[[REG:[a-z]+]]
; CHECK-NEXT: addq %rdi, %[[REG]]
; CHECK-NEXT: seto
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -21474836489)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -169,12 +151,9 @@ entry:
define zeroext i1 @saddo.i64imm4(i64 %v1, i64* %res) {
entry:
; DAG-LABEL: saddo.i64imm4
; DAG: addq $2147483647, %rdi
; DAG-NEXT: seto
; FAST-LABEL: saddo.i64imm4
; FAST: addq $2147483647, %rdi
; FAST-NEXT: seto
; CHECK-LABEL: saddo.i64imm4
; CHECK: addq $2147483647, %rdi
; CHECK-NEXT: seto
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483647)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -182,17 +161,12 @@ entry:
ret i1 %obit
}
; TODO: FastISel shouldn't use movabsq.
define zeroext i1 @saddo.i64imm5(i64 %v1, i64* %res) {
entry:
; DAG-LABEL: saddo.i64imm5
; DAG: movl $2147483648, %ecx
; DAG: addq %rdi, %rcx
; DAG-NEXT: seto
; FAST-LABEL: saddo.i64imm5
; FAST: movabsq $2147483648, %[[REG:[a-z]+]]
; FAST: addq %rdi, %[[REG]]
; FAST-NEXT: seto
; CHECK-LABEL: saddo.i64imm5
; CHECK: movl $2147483648
; CHECK: addq %rdi
; CHECK-NEXT: seto
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483648)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -203,12 +177,9 @@ entry:
; UADDO
define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
entry:
; DAG-LABEL: uaddo.i32
; DAG: addl %esi, %edi
; DAG-NEXT: setb %al
; FAST-LABEL: uaddo.i32
; FAST: addl %esi, %edi
; FAST-NEXT: setb %al
; CHECK-LABEL: uaddo.i32
; CHECK: addl %esi, %edi
; CHECK-NEXT: setb %al
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -218,12 +189,9 @@ entry:
define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
entry:
; DAG-LABEL: uaddo.i64
; DAG: addq %rsi, %rdi
; DAG-NEXT: setb %al
; FAST-LABEL: uaddo.i64
; FAST: addq %rsi, %rdi
; FAST-NEXT: setb %al
; CHECK-LABEL: uaddo.i64
; CHECK: addq %rsi, %rdi
; CHECK-NEXT: setb %al
%t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -279,12 +247,9 @@ entry:
; SSUBO
define zeroext i1 @ssubo.i32(i32 %v1, i32 %v2, i32* %res) {
entry:
; DAG-LABEL: ssubo.i32
; DAG: subl %esi, %edi
; DAG-NEXT: seto %al
; FAST-LABEL: ssubo.i32
; FAST: subl %esi, %edi
; FAST-NEXT: seto %al
; CHECK-LABEL: ssubo.i32
; CHECK: subl %esi, %edi
; CHECK-NEXT: seto %al
%t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -294,12 +259,9 @@ entry:
define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
entry:
; DAG-LABEL: ssubo.i64
; DAG: subq %rsi, %rdi
; DAG-NEXT: seto %al
; FAST-LABEL: ssubo.i64
; FAST: subq %rsi, %rdi
; FAST-NEXT: seto %al
; CHECK-LABEL: ssubo.i64
; CHECK: subq %rsi, %rdi
; CHECK-NEXT: seto %al
%t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -310,12 +272,9 @@ entry:
; USUBO
define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
entry:
; DAG-LABEL: usubo.i32
; DAG: subl %esi, %edi
; DAG-NEXT: setb %al
; FAST-LABEL: usubo.i32
; FAST: subl %esi, %edi
; FAST-NEXT: setb %al
; CHECK-LABEL: usubo.i32
; CHECK: subl %esi, %edi
; CHECK-NEXT: setb %al
%t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -325,12 +284,9 @@ entry:
define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
entry:
; DAG-LABEL: usubo.i64
; DAG: subq %rsi, %rdi
; DAG-NEXT: setb %al
; FAST-LABEL: usubo.i64
; FAST: subq %rsi, %rdi
; FAST-NEXT: setb %al
; CHECK-LABEL: usubo.i64
; CHECK: subq %rsi, %rdi
; CHECK-NEXT: setb %al
%t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -354,12 +310,9 @@ entry:
define zeroext i1 @smulo.i16(i16 %v1, i16 %v2, i16* %res) {
entry:
; DAG-LABEL: smulo.i16
; DAG: imulw %si, %di
; DAG-NEXT: seto %al
; FAST-LABEL: smulo.i16
; FAST: imulw %si, %di
; FAST-NEXT: seto %al
; CHECK-LABEL: smulo.i16
; CHECK: imulw %si, %di
; CHECK-NEXT: seto %al
%t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
%val = extractvalue {i16, i1} %t, 0
%obit = extractvalue {i16, i1} %t, 1
@ -369,12 +322,9 @@ entry:
define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
entry:
; DAG-LABEL: smulo.i32
; DAG: imull %esi, %edi
; DAG-NEXT: seto %al
; FAST-LABEL: smulo.i32
; FAST: imull %esi, %edi
; FAST-NEXT: seto %al
; CHECK-LABEL: smulo.i32
; CHECK: imull %esi, %edi
; CHECK-NEXT: seto %al
%t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -384,12 +334,9 @@ entry:
define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
entry:
; DAG-LABEL: smulo.i64
; DAG: imulq %rsi, %rdi
; DAG-NEXT: seto %al
; FAST-LABEL: smulo.i64
; FAST: imulq %rsi, %rdi
; FAST-NEXT: seto %al
; CHECK-LABEL: smulo.i64
; CHECK: imulq %rsi, %rdi
; CHECK-NEXT: seto %al
%t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -413,12 +360,9 @@ entry:
define zeroext i1 @umulo.i16(i16 %v1, i16 %v2, i16* %res) {
entry:
; DAG-LABEL: umulo.i16
; DAG: mulw %si
; DAG-NEXT: seto
; FAST-LABEL: umulo.i16
; FAST: mulw %si
; FAST-NEXT: seto
; CHECK-LABEL: umulo.i16
; CHECK: mulw %si
; CHECK-NEXT: seto
%t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
%val = extractvalue {i16, i1} %t, 0
%obit = extractvalue {i16, i1} %t, 1
@ -428,12 +372,9 @@ entry:
define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
entry:
; DAG-LABEL: umulo.i32
; DAG: mull %esi
; DAG-NEXT: seto
; FAST-LABEL: umulo.i32
; FAST: mull %esi
; FAST-NEXT: seto
; CHECK-LABEL: umulo.i32
; CHECK: mull %esi
; CHECK-NEXT: seto
%t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -443,12 +384,9 @@ entry:
define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
entry:
; DAG-LABEL: umulo.i64
; DAG: mulq %rsi
; DAG-NEXT: seto
; FAST-LABEL: umulo.i64
; FAST: mulq %rsi
; FAST-NEXT: seto
; CHECK-LABEL: umulo.i64
; CHECK: mulq %rsi
; CHECK-NEXT: seto
%t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -461,9 +399,9 @@ entry:
;
define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: saddo.select.i32
; CHECK: addl %esi, %eax
; CHECK-NEXT: cmovol %edi, %esi
; CHECK-LABEL: saddo.select.i32
; CHECK: addl %esi, %eax
; CHECK-NEXT: cmovol %edi, %esi
%t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
%obit = extractvalue {i32, i1} %t, 1
%ret = select i1 %obit, i32 %v1, i32 %v2
@ -472,9 +410,9 @@ entry:
define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: saddo.select.i64
; CHECK: addq %rsi, %rax
; CHECK-NEXT: cmovoq %rdi, %rsi
; CHECK-LABEL: saddo.select.i64
; CHECK: addq %rsi, %rax
; CHECK-NEXT: cmovoq %rdi, %rsi
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
%obit = extractvalue {i64, i1} %t, 1
%ret = select i1 %obit, i64 %v1, i64 %v2
@ -483,9 +421,9 @@ entry:
define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: uaddo.select.i32
; CHECK: addl %esi, %eax
; CHECK-NEXT: cmovbl %edi, %esi
; CHECK-LABEL: uaddo.select.i32
; CHECK: addl %esi, %eax
; CHECK-NEXT: cmovbl %edi, %esi
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
%obit = extractvalue {i32, i1} %t, 1
%ret = select i1 %obit, i32 %v1, i32 %v2
@ -494,9 +432,9 @@ entry:
define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: uaddo.select.i64
; CHECK: addq %rsi, %rax
; CHECK-NEXT: cmovbq %rdi, %rsi
; CHECK-LABEL: uaddo.select.i64
; CHECK: addq %rsi, %rax
; CHECK-NEXT: cmovbq %rdi, %rsi
%t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
%obit = extractvalue {i64, i1} %t, 1
%ret = select i1 %obit, i64 %v1, i64 %v2
@ -505,9 +443,9 @@ entry:
define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: ssubo.select.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: cmovol %edi, %esi
; CHECK-LABEL: ssubo.select.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: cmovol %edi, %esi
%t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
%obit = extractvalue {i32, i1} %t, 1
%ret = select i1 %obit, i32 %v1, i32 %v2
@ -516,9 +454,9 @@ entry:
define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: ssubo.select.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: cmovoq %rdi, %rsi
; CHECK-LABEL: ssubo.select.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: cmovoq %rdi, %rsi
%t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
%obit = extractvalue {i64, i1} %t, 1
%ret = select i1 %obit, i64 %v1, i64 %v2
@ -527,9 +465,9 @@ entry:
define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: usubo.select.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: cmovbl %edi, %esi
; CHECK-LABEL: usubo.select.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: cmovbl %edi, %esi
%t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
%obit = extractvalue {i32, i1} %t, 1
%ret = select i1 %obit, i32 %v1, i32 %v2
@ -538,9 +476,9 @@ entry:
define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: usubo.select.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: cmovbq %rdi, %rsi
; CHECK-LABEL: usubo.select.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: cmovbq %rdi, %rsi
%t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
%obit = extractvalue {i64, i1} %t, 1
%ret = select i1 %obit, i64 %v1, i64 %v2
@ -549,9 +487,9 @@ entry:
define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: smulo.select.i32
; CHECK: imull %esi, %eax
; CHECK-NEXT: cmovol %edi, %esi
; CHECK-LABEL: smulo.select.i32
; CHECK: imull %esi, %eax
; CHECK-NEXT: cmovol %edi, %esi
%t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
%obit = extractvalue {i32, i1} %t, 1
%ret = select i1 %obit, i32 %v1, i32 %v2
@ -560,9 +498,9 @@ entry:
define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: smulo.select.i64
; CHECK: imulq %rsi, %rax
; CHECK-NEXT: cmovoq %rdi, %rsi
; CHECK-LABEL: smulo.select.i64
; CHECK: imulq %rsi, %rax
; CHECK-NEXT: cmovoq %rdi, %rsi
%t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
%obit = extractvalue {i64, i1} %t, 1
%ret = select i1 %obit, i64 %v1, i64 %v2
@ -571,9 +509,9 @@ entry:
define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: umulo.select.i32
; CHECK: mull %esi
; CHECK-NEXT: cmovol %edi, %esi
; CHECK-LABEL: umulo.select.i32
; CHECK: mull %esi
; CHECK-NEXT: cmovol %edi, %esi
%t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
%obit = extractvalue {i32, i1} %t, 1
%ret = select i1 %obit, i32 %v1, i32 %v2
@ -582,9 +520,9 @@ entry:
define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: umulo.select.i64
; CHECK: mulq %rsi
; CHECK-NEXT: cmovoq %rdi, %rsi
; CHECK-LABEL: umulo.select.i64
; CHECK: mulq %rsi
; CHECK-NEXT: cmovoq %rdi, %rsi
%t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
%obit = extractvalue {i64, i1} %t, 1
%ret = select i1 %obit, i64 %v1, i64 %v2
@ -597,9 +535,9 @@ entry:
;
define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: saddo.br.i32
; CHECK: addl %esi, %edi
; CHECK-NEXT: jo
; CHECK-LABEL: saddo.br.i32
; CHECK: addl %esi, %edi
; CHECK-NEXT: jo
%t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -614,9 +552,9 @@ continue:
define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: saddo.br.i64
; CHECK: addq %rsi, %rdi
; CHECK-NEXT: jo
; CHECK-LABEL: saddo.br.i64
; CHECK: addq %rsi, %rdi
; CHECK-NEXT: jo
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -631,9 +569,9 @@ continue:
define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: uaddo.br.i32
; CHECK: addl %esi, %edi
; CHECK-NEXT: jb
; CHECK-LABEL: uaddo.br.i32
; CHECK: addl %esi, %edi
; CHECK-NEXT: jb
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -648,9 +586,9 @@ continue:
define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: uaddo.br.i64
; CHECK: addq %rsi, %rdi
; CHECK-NEXT: jb
; CHECK-LABEL: uaddo.br.i64
; CHECK: addq %rsi, %rdi
; CHECK-NEXT: jb
%t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -665,9 +603,9 @@ continue:
define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: ssubo.br.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: jo
; CHECK-LABEL: ssubo.br.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: jo
%t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -682,9 +620,9 @@ continue:
define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: ssubo.br.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: jo
; CHECK-LABEL: ssubo.br.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: jo
%t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -699,9 +637,9 @@ continue:
define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: usubo.br.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: jb
; CHECK-LABEL: usubo.br.i32
; CHECK: cmpl %esi, %edi
; CHECK-NEXT: jb
%t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -716,9 +654,9 @@ continue:
define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: usubo.br.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: jb
; CHECK-LABEL: usubo.br.i64
; CHECK: cmpq %rsi, %rdi
; CHECK-NEXT: jb
%t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -733,9 +671,9 @@ continue:
define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: smulo.br.i32
; CHECK: imull %esi, %edi
; CHECK-NEXT: jo
; CHECK-LABEL: smulo.br.i32
; CHECK: imull %esi, %edi
; CHECK-NEXT: jo
%t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -750,9 +688,9 @@ continue:
define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: smulo.br.i64
; CHECK: imulq %rsi, %rdi
; CHECK-NEXT: jo
; CHECK-LABEL: smulo.br.i64
; CHECK: imulq %rsi, %rdi
; CHECK-NEXT: jo
%t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1
@ -767,9 +705,9 @@ continue:
define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
entry:
; CHECK-LABEL: umulo.br.i32
; CHECK: mull %esi
; CHECK-NEXT: jo
; CHECK-LABEL: umulo.br.i32
; CHECK: mull %esi
; CHECK-NEXT: jo
%t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
%val = extractvalue {i32, i1} %t, 0
%obit = extractvalue {i32, i1} %t, 1
@ -784,9 +722,9 @@ continue:
define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
entry:
; CHECK-LABEL: umulo.br.i64
; CHECK: mulq %rsi
; CHECK-NEXT: jo
; CHECK-LABEL: umulo.br.i64
; CHECK: mulq %rsi
; CHECK-NEXT: jo
%t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
%val = extractvalue {i64, i1} %t, 0
%obit = extractvalue {i64, i1} %t, 1