diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 5629debe802..66335ed6ce5 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -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(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; diff --git a/test/Transforms/CorrelatedValuePropagation/overflows.ll b/test/Transforms/CorrelatedValuePropagation/overflows.ll index 04b1471ebb4..0b7fc0dfe02 100644 --- a/test/Transforms/CorrelatedValuePropagation/overflows.ll +++ b/test/Transforms/CorrelatedValuePropagation/overflows.ll @@ -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: