From fdc6977ff3c0cb6c729c38c86f96e1281cb3171c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 7 Sep 2019 12:03:59 +0000 Subject: [PATCH] [LVI] Look through extractvalue of insertvalue This addresses the issue mentioned on D19867. When we simplify with.overflow instructions in CVP, we leave behind extractvalue of insertvalue sequences that LVI no longer understands. This means that we can not simplify any instructions based on the with.overflow anymore (until some over pass like InstCombine cleans them up). This patch extends LVI extractvalue handling by calling SimplifyExtractValueInst (which doesn't do anything more than constant folding + looking through insertvalue) and using the block value of the simplification. A possible alternative would be to do something similar to SimplifyIndVars, where we instead directly try to replace extractvalue users of the with.overflow. This would need some additional structural changes to CVP, as it's currently not legal to remove anything but the current instruction -- we'd have to introduce a worklist with instructions scheduled for deletion or similar. Differential Revision: https://reviews.llvm.org/D67035 llvm-svn: 371306 --- llvm/lib/Analysis/LazyValueInfo.cpp | 15 +++++++++++ .../CorrelatedValuePropagation/overflows.ll | 27 +++++-------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 541fc876a21d..96722f32e355 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1141,6 +1141,21 @@ bool LazyValueInfoImpl::solveBlockValueExtractValue( if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 0) return solveBlockValueOverflowIntrinsic(BBLV, WO, BB); + // Handle extractvalue of insertvalue to allow further simplification + // based on replaced with.overflow intrinsics. + if (Value *V = SimplifyExtractValueInst( + EVI->getAggregateOperand(), EVI->getIndices(), + EVI->getModule()->getDataLayout())) { + if (!hasBlockValue(V, BB)) { + if (pushBlockValue({ BB, V })) + return false; + BBLV = ValueLatticeElement::getOverdefined(); + return true; + } + BBLV = getBlockValue(V, BB); + return true; + } + LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined (unknown extractvalue).\n"); BBLV = ValueLatticeElement::getOverdefined(); diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/overflows.ll b/llvm/test/Transforms/CorrelatedValuePropagation/overflows.ll index 7f021a47f64b..39964682bf24 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/overflows.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/overflows.ll @@ -850,11 +850,9 @@ define i1 @sadd_and_cmp(i32 %x, i32 %y) #0 { ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 ; CHECK-NEXT: br label [[CONT3:%.*]] ; CHECK: cont3: -; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[ADD]], 19 ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: -; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; entry: %x.offset = add i32 %x, 9 @@ -897,11 +895,9 @@ define i1 @uadd_and_cmp(i32 %x, i32 %y) #0 { ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 ; CHECK-NEXT: br label [[CONT3:%.*]] ; CHECK: cont3: -; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[ADD]], 19 ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: -; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; entry: %cmp1 = icmp ult i32 %x, 10 @@ -940,11 +936,9 @@ define i1 @ssub_and_cmp(i32 %x, i32 %y) #0 { ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 ; CHECK-NEXT: br label [[CONT3:%.*]] ; CHECK: cont3: -; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[SUB]], 19 ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: -; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; entry: %cmp1 = icmp ult i32 %x, 10 @@ -985,11 +979,9 @@ define i1 @usub_and_cmp(i32 %x, i32 %y) #0 { ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 ; CHECK-NEXT: br label [[CONT3:%.*]] ; CHECK: cont3: -; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[SUB]], 19 ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: -; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; entry: %cmp1 = icmp ult i32 %x, 10 @@ -1031,13 +1023,10 @@ define i1 @smul_and_cmp(i32 %x, i32 %y) #0 { ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 ; CHECK-NEXT: br label [[CONT3:%.*]] ; CHECK: cont3: -; CHECK-NEXT: [[CMP3:%.*]] = icmp sle i32 [[MUL]], 81 -; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[MUL]], -81 -; CHECK-NEXT: [[CMP5:%.*]] = and i1 [[CMP3]], [[CMP4]] +; CHECK-NEXT: [[CMP5:%.*]] = and i1 true, true ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: -; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP5]], [[CONT3]] ] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; entry: %x.offset = add i32 %x, 9 @@ -1080,11 +1069,9 @@ define i1 @umul_and_cmp(i32 %x, i32 %y) #0 { ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 ; CHECK-NEXT: br label [[CONT3:%.*]] ; CHECK: cont3: -; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[MUL]], 9801 ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: -; CHECK-NEXT: [[RET:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ true, [[CONT1]] ], [ [[CMP3]], [[CONT3]] ] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; entry: %cmp1 = icmp ult i32 %x, 100