diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -816,16 +816,16 @@ } void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { - // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would - // discover a concrete value later. - if (isOverdefined(ValueState[&EVI])) - return (void)markOverdefined(&EVI); - // If this returns a struct, mark all elements over defined, we don't track // structs in structs. if (EVI.getType()->isStructTy()) return (void)markOverdefined(&EVI); + // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would + // discover a concrete value later. + if (ValueState[&EVI].isOverdefined()) + return (void)markOverdefined(&EVI); + // If this is extracting from more than one level of struct, we don't know. if (EVI.getNumIndices() != 1) return (void)markOverdefined(&EVI); diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll --- a/llvm/test/Transforms/SCCP/conditions-ranges.ll +++ b/llvm/test/Transforms/SCCP/conditions-ranges.ll @@ -989,6 +989,12 @@ ; CHECK-NEXT: call void @use(i1 [[F_2]]) ; CHECK-NEXT: [[F_3:%.*]] = icmp ugt i32 [[A]], 100 ; CHECK-NEXT: call void @use(i1 [[F_3]]) +; CHECK-NEXT: [[F_4:%.*]] = icmp eq i32 [[B]], 0 +; CHECK-NEXT: call void @use(i1 [[F_3]]) +; CHECK-NEXT: [[F_5:%.*]] = icmp eq i32 [[B]], 20 +; CHECK-NEXT: call void @use(i1 [[F_5]]) +; CHECK-NEXT: [[F_6:%.*]] = icmp ugt i32 [[B]], 100 +; CHECK-NEXT: call void @use(i1 [[F_6]]) ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 100 ; CHECK-NEXT: call void @use(i1 [[T_1]]) ; CHECK-NEXT: [[T_2:%.*]] = icmp ne i32 [[A]], 20 @@ -1001,8 +1007,8 @@ ; CHECK-NEXT: call void @use(i1 [[C_3]]) ; CHECK-NEXT: ret void ; CHECK: false: -; CHECK-NEXT: [[F_4:%.*]] = icmp eq i32 [[A]], 50 -; CHECK-NEXT: call void @use(i1 [[F_4]]) +; CHECK-NEXT: [[F_7:%.*]] = icmp eq i32 [[A]], 50 +; CHECK-NEXT: call void @use(i1 [[F_7]]) ; CHECK-NEXT: [[T_3:%.*]] = icmp ne i32 [[A]], 50 ; CHECK-NEXT: call void @use(i1 [[T_3]]) ; CHECK-NEXT: [[C_4:%.*]] = icmp eq i32 [[A]], 10 @@ -1027,6 +1033,13 @@ call void @use(i1 %f.2) %f.3 = icmp ugt i32 %a, 100 call void @use(i1 %f.3) + %f.4 = icmp eq i32 %b, 0 + call void @use(i1 %f.3) + %f.5 = icmp eq i32 %b, 20 + call void @use(i1 %f.5) + %f.6 = icmp ugt i32 %b, 100 + call void @use(i1 %f.6) + ; Conditions below are true. %t.1 = icmp ult i32 %a, 100 @@ -1045,8 +1058,8 @@ false: ; Conditions below are false; - %f.4 = icmp eq i32 %a, 50 - call void @use(i1 %f.4) + %f.7 = icmp eq i32 %a, 50 + call void @use(i1 %f.7) ; Conditions below are true; %t.3 = icmp ne i32 %a, 50 diff --git a/llvm/test/Transforms/SCCP/constant-range-struct.ll b/llvm/test/Transforms/SCCP/constant-range-struct.ll --- a/llvm/test/Transforms/SCCP/constant-range-struct.ll +++ b/llvm/test/Transforms/SCCP/constant-range-struct.ll @@ -104,16 +104,12 @@ ; CHECK-NEXT: [[V2:%.*]] = extractvalue { i64, i64 } [[S]], 1 ; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: call void @use(i1 true) -; CHECK-NEXT: [[T_3:%.*]] = icmp ne i64 [[V2]], 0 -; CHECK-NEXT: call void @use(i1 [[T_3]]) -; CHECK-NEXT: [[T_4:%.*]] = icmp ult i64 [[V2]], 301 -; CHECK-NEXT: call void @use(i1 [[T_4]]) +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 false) ; CHECK-NEXT: call void @use(i1 false) -; CHECK-NEXT: [[F_3:%.*]] = icmp eq i64 [[V2]], 50 -; CHECK-NEXT: call void @use(i1 [[F_3]]) -; CHECK-NEXT: [[F_4:%.*]] = icmp ugt i64 [[V2]], 301 -; CHECK-NEXT: call void @use(i1 [[F_4]]) ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i64 [[V1]], 25 ; CHECK-NEXT: call void @use(i1 [[C_1]]) ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i64 [[V1]], 25 @@ -155,6 +151,5 @@ %c.4 = icmp ugt i64 %v2, 250 call void @use(i1 %c.4) - ret void }