[CVP] Generate simpler code for elided with.overflow intrinsics

Use a { iN undef, i1 false } struct as the base, and only insert
the first operand, instead of using { iN undef, i1 undef } as the
base and inserting both. This is the same as what we do in InstCombine.

Differential Revision: https://reviews.llvm.org/D67034

llvm-svn: 370573
This commit is contained in:
Nikita Popov 2019-08-31 09:58:37 +00:00
parent 04a4c0910b
commit b9e668f2e7
2 changed files with 103 additions and 114 deletions

View File

@ -417,6 +417,7 @@ static bool willNotOverflow(BinaryOpIntrinsic *BO, LazyValueInfo *LVI) {
return NWRegion.contains(LRange);
}
// Rewrite this with.overflow intrinsic as non-overflowing.
static void processOverflowIntrinsic(WithOverflowInst *WO) {
IRBuilder<> B(WO);
Value *NewOp = B.CreateBinOp(
@ -429,8 +430,11 @@ static void processOverflowIntrinsic(WithOverflowInst *WO) {
Inst->setHasNoUnsignedWrap();
}
Value *NewI = B.CreateInsertValue(UndefValue::get(WO->getType()), NewOp, 0);
NewI = B.CreateInsertValue(NewI, ConstantInt::getFalse(WO->getContext()), 1);
StructType *ST = cast<StructType>(WO->getType());
Constant *Struct = ConstantStruct::get(ST,
{ UndefValue::get(ST->getElementType(0)),
ConstantInt::getFalse(ST->getElementType(1)) });
Value *NewI = B.CreateInsertValue(Struct, NewOp, 0);
WO->replaceAllUsesWith(NewI);
WO->eraseFromParent();
++NumOverflows;

View File

@ -39,37 +39,35 @@ define i32 @signed_add(i32 %x, i32 %y) {
; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
; CHECK: land.lhs.true:
; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i32 2147483647, [[Y]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cont:
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP4]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP3]], [[X:%.*]]
; CHECK-NEXT: br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: lor.lhs.false:
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y]], 0
; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_LHS_TRUE3:%.*]], label [[COND_FALSE]]
; CHECK: land.lhs.true3:
; CHECK-NEXT: [[TMP5:%.*]] = sub nsw i32 -2147483648, [[Y]]
; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP5]], 0
; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i32, i1 } [[TMP6]], i1 false, 1
; CHECK-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
; CHECK-NEXT: br i1 [[TMP8]], label [[TRAP]], label [[CONT4:%.*]]
; CHECK-NEXT: [[TMP4:%.*]] = sub nsw i32 -2147483648, [[Y]]
; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP4]], 0
; CHECK-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
; CHECK-NEXT: br i1 [[TMP6]], label [[TRAP]], label [[CONT4:%.*]]
; CHECK: cont4:
; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP7]], 0
; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[X]]
; CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP7]], [[X]]
; CHECK-NEXT: br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP10:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: [[TMP11:%.*]] = extractvalue { i32, i1 } [[TMP10]], 0
; CHECK-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP10]], 1
; CHECK-NEXT: br i1 [[TMP12]], label [[TRAP]], label [[COND_END]]
; CHECK-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
; CHECK-NEXT: [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
; CHECK-NEXT: br i1 [[TMP10]], label [[TRAP]], label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP11]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP9]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -119,24 +117,23 @@ define i32 @unsigned_add(i32 %x, i32 %y) {
; CHECK-LABEL: @unsigned_add(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = sub nuw i32 -1, [[Y:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cont:
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP4]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[TMP3]], [[X:%.*]]
; CHECK-NEXT: br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP5:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
; CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
; CHECK-NEXT: br i1 [[TMP7]], label [[TRAP]], label [[COND_END]]
; CHECK-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
; CHECK-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1
; CHECK-NEXT: br i1 [[TMP6]], label [[TRAP]], label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[CONT]] ], [ [[TMP6]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[CONT]] ], [ [[TMP5]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -171,37 +168,35 @@ define i32 @signed_sub(i32 %x, i32 %y) {
; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_LHS_FALSE:%.*]]
; CHECK: land.lhs.true:
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[Y]], 2147483647
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT:%.*]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cont:
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP4]], [[X:%.*]]
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[TMP3]], [[X:%.*]]
; CHECK-NEXT: br i1 [[CMP1]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: lor.lhs.false:
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[Y]], 0
; CHECK-NEXT: br i1 [[CMP2]], label [[COND_FALSE]], label [[LAND_LHS_TRUE3:%.*]]
; CHECK: land.lhs.true3:
; CHECK-NEXT: [[TMP5:%.*]] = add nsw i32 [[Y]], -2147483648
; CHECK-NEXT: [[TMP6:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP5]], 0
; CHECK-NEXT: [[TMP7:%.*]] = insertvalue { i32, i1 } [[TMP6]], i1 false, 1
; CHECK-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
; CHECK-NEXT: br i1 [[TMP8]], label [[TRAP]], label [[CONT4:%.*]]
; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[Y]], -2147483648
; CHECK-NEXT: [[TMP5:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP4]], 0
; CHECK-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP5]], 1
; CHECK-NEXT: br i1 [[TMP6]], label [[TRAP]], label [[CONT4:%.*]]
; CHECK: cont4:
; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP7]], 0
; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP9]], [[X]]
; CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP5]], 0
; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP7]], [[X]]
; CHECK-NEXT: br i1 [[CMP5]], label [[COND_END]], label [[COND_FALSE]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP10:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: [[TMP11:%.*]] = extractvalue { i32, i1 } [[TMP10]], 0
; CHECK-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP10]], 1
; CHECK-NEXT: br i1 [[TMP12]], label [[TRAP]], label [[COND_END]]
; CHECK-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0
; CHECK-NEXT: [[TMP10:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
; CHECK-NEXT: br i1 [[TMP10]], label [[TRAP]], label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP11]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[CONT4]] ], [ 0, [[CONT]] ], [ [[TMP9]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -290,16 +285,15 @@ define i32 @signed_add_r1(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -328,16 +322,15 @@ define i32 @unsigned_add_r1(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = add nuw i32 [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -366,16 +359,15 @@ define i32 @signed_sub_r1(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i32 [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -404,16 +396,15 @@ define i32 @unsigned_sub_r1(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = sub nuw i32 [[X]], 1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -442,16 +433,15 @@ define i32 @signed_add_rn1(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[X]], -1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -480,16 +470,15 @@ define i32 @signed_sub_rn1(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[TMP0:%.*]] = sub nsw i32 [[X]], -1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP4]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP3]], [[COND_FALSE]] ]
; CHECK-NEXT: [[COND:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[COND_FALSE]] ]
; CHECK-NEXT: ret i32 [[COND]]
;
entry:
@ -518,10 +507,9 @@ define i32 @unsigned_mul(i32 %x) {
; CHECK-NEXT: br i1 [[CMP]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[MULO1:%.*]] = mul nuw i32 [[X]], 100
; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i32, i1 } undef, i32 [[MULO1]], 0
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } [[TMP0]], i1 false, 1
; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[MULO1]], 0
; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
@ -558,10 +546,9 @@ define i32 @signed_mul(i32 %x) {
; CHECK-NEXT: br i1 [[CMP3]], label [[COND_END:%.*]], label [[COND_FALSE:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: [[MULO1:%.*]] = mul nsw i32 [[X]], 100
; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i32, i1 } undef, i32 [[MULO1]], 0
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } [[TMP0]], i1 false, 1
; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: [[TMP0:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[MULO1]], 0
; CHECK-NEXT: [[RES:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0
; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1
; CHECK-NEXT: br i1 [[OV]], label [[TRAP:%.*]], label [[COND_END]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
@ -601,19 +588,18 @@ define void @unsigned_loop(i32 %i) {
; CHECK: while.body.preheader:
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
; CHECK: while.body:
; CHECK-NEXT: [[I_ADDR_04:%.*]] = phi i32 [ [[TMP4:%.*]], [[CONT:%.*]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
; CHECK-NEXT: [[I_ADDR_04:%.*]] = phi i32 [ [[TMP3:%.*]], [[CONT:%.*]] ], [ [[I]], [[WHILE_BODY_PREHEADER]] ]
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @bar(i32 [[I_ADDR_04]])
; CHECK-NEXT: [[TMP0:%.*]] = sub nuw i32 [[I_ADDR_04]], 1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cont:
; CHECK-NEXT: [[TMP4]] = extractvalue { i32, i1 } [[TMP2]], 0
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP4]], 0
; CHECK-NEXT: [[TMP3]] = extractvalue { i32, i1 } [[TMP1]], 0
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_END]], label [[WHILE_BODY]]
; CHECK: while.end:
; CHECK-NEXT: ret void
@ -651,33 +637,32 @@ define void @intrinsic_into_phi(i32 %n) {
; CHECK-NEXT: br label [[CONT:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[DOTLCSSA:%.*]], 1
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } undef, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue { i32, i1 } [[TMP1]], i1 false, 1
; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1
; CHECK-NEXT: br i1 [[TMP3]], label [[TRAP:%.*]], label [[CONT]]
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[TMP0]], 0
; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
; CHECK-NEXT: br i1 [[TMP2]], label [[TRAP:%.*]], label [[CONT]]
; CHECK: trap:
; CHECK-NEXT: tail call void @llvm.trap()
; CHECK-NEXT: unreachable
; CHECK: cont:
; CHECK-NEXT: [[TMP4:%.*]] = phi { i32, i1 } [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP2]], [[FOR_COND:%.*]] ]
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0
; CHECK-NEXT: [[CALL9:%.*]] = tail call i32 @bar(i32 [[TMP5]])
; CHECK-NEXT: [[TMP3:%.*]] = phi { i32, i1 } [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP1]], [[FOR_COND:%.*]] ]
; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0
; CHECK-NEXT: [[CALL9:%.*]] = tail call i32 @bar(i32 [[TMP4]])
; CHECK-NEXT: [[TOBOOL10:%.*]] = icmp eq i32 [[CALL9]], 0
; CHECK-NEXT: br i1 [[TOBOOL10]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
; CHECK: while.body.preheader:
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
; CHECK: while.cond:
; CHECK-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP8:%.*]], 0
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @bar(i32 [[TMP6]])
; CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP7:%.*]], 0
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @bar(i32 [[TMP5]])
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[CALL]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label [[WHILE_END]], label [[WHILE_BODY]]
; CHECK: while.body:
; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP6]], [[WHILE_COND:%.*]] ], [ [[TMP5]], [[WHILE_BODY_PREHEADER]] ]
; CHECK-NEXT: [[TMP8]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP7]], i32 1)
; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1
; CHECK-NEXT: br i1 [[TMP9]], label [[TRAP]], label [[WHILE_COND]]
; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP5]], [[WHILE_COND:%.*]] ], [ [[TMP4]], [[WHILE_BODY_PREHEADER]] ]
; CHECK-NEXT: [[TMP7]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP6]], i32 1)
; CHECK-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP7]], 1
; CHECK-NEXT: br i1 [[TMP8]], label [[TRAP]], label [[WHILE_COND]]
; CHECK: while.end:
; CHECK-NEXT: [[DOTLCSSA]] = phi i32 [ [[TMP5]], [[CONT]] ], [ [[TMP6]], [[WHILE_COND]] ]
; CHECK-NEXT: [[DOTLCSSA]] = phi i32 [ [[TMP4]], [[CONT]] ], [ [[TMP5]], [[WHILE_COND]] ]
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[DOTLCSSA]], [[N:%.*]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND]], label [[CLEANUP2:%.*]]
; CHECK: cleanup2: