return;
}
- // TODO: Actually filp MayIncludeUndef for the created range to false,
- // once most places in the optimizer respect the branches on
- // undef/poison are UB rule. The reason why the new range cannot be
- // undef is as follows below:
- // The new range is based on a branch condition. That guarantees that
- // neither of the compare operands can be undef in the branch targets,
- // unless we have conditions that are always true/false (e.g. icmp ule
- // i32, %a, i32_max). For the latter overdefined/empty range will be
- // inferred, but the branch will get folded accordingly anyways.
- bool MayIncludeUndef = !isa<PredicateAssume>(PI);
-
ValueLatticeElement CondVal = getValueState(OtherOp);
ValueLatticeElement &IV = ValueState[&CB];
if (CondVal.isConstantRange() || CopyOfVal.isConstantRange()) {
if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
NewCR = CopyOfCR;
+ // The new range is based on a branch condition. That guarantees that
+ // neither of the compare operands can be undef in the branch targets,
+ // unless we have conditions that are always true/false (e.g. icmp ule
+ // i32, %a, i32_max). For the latter overdefined/empty range will be
+ // inferred, but the branch will get folded accordingly anyways.
addAdditionalUser(OtherOp, &CB);
- mergeInValue(IV, &CB,
- ValueLatticeElement::getRange(NewCR, MayIncludeUndef));
+ mergeInValue(
+ IV, &CB,
+ ValueLatticeElement::getRange(NewCR, /*MayIncludeUndef*/ false));
return;
} else if (Pred == CmpInst::ICMP_EQ && CondVal.isConstant()) {
// For non-integer values or integer constant expressions, only
addAdditionalUser(OtherOp, &CB);
mergeInValue(IV, &CB, CondVal);
return;
- } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant() &&
- !MayIncludeUndef) {
+ } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant()) {
// Propagate inequalities.
addAdditionalUser(OtherOp, &CB);
mergeInValue(IV, &CB,
ret void
}
-; TODO: Use information %a != 0 in false branch.
define void @f2_ptr(i8* %a, i8* %b) {
; CHECK-LABEL: @f2_ptr(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @use(i1 [[C_1]])
; CHECK-NEXT: ret void
; CHECK: false:
-; CHECK-NEXT: [[F_2:%.*]] = icmp eq i8* [[A]], null
-; CHECK-NEXT: call void @use(i1 [[F_2]])
-; CHECK-NEXT: [[T_2:%.*]] = icmp ne i8* [[A]], null
-; CHECK-NEXT: call void @use(i1 [[T_2]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8* [[A]], [[B]]
; CHECK-NEXT: call void @use(i1 [[C_2]])
; CHECK-NEXT: ret void
; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], 0
; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
-; CHECK-NEXT: [[EXT_1:%.*]] = sext i32 [[X]] to i64
+; CHECK-NEXT: [[EXT_1:%.*]] = zext i32 [[X]] to i64
; CHECK-NEXT: ret i64 [[EXT_1]]
; CHECK: false:
; CHECK-NEXT: [[EXT_2:%.*]] = sext i32 [[X]] to i64
; CHECK-NEXT: [[C:%.*]] = icmp sge i32 [[X:%.*]], 0
; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
; CHECK: true:
-; CHECK-NEXT: [[EXT_1:%.*]] = sext i32 [[X]] to i64
+; CHECK-NEXT: [[EXT_1:%.*]] = zext i32 [[X]] to i64
; CHECK-NEXT: ret i64 [[EXT_1]]
; CHECK: false:
; CHECK-NEXT: [[EXT_2:%.*]] = sext i32 [[X]] to i64
define i64 @test5(i32 %x) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: [[P:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[P]] to i64
-; CHECK-NEXT: ret i64 [[TMP1]]
+; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[P]] to i64
+; CHECK-NEXT: ret i64 [[EXT]]
;
%p = and i32 %x, 15
%ext = sext i32 %p to i64
define i64 @test7(i16 %x) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: [[P:%.*]] = and i16 [[X:%.*]], 15
-; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[P]] to i32
-; CHECK-NEXT: [[EXT_2:%.*]] = sext i32 [[TMP1]] to i64
+; CHECK-NEXT: [[EXT_1:%.*]] = zext i16 [[P]] to i32
+; CHECK-NEXT: [[EXT_2:%.*]] = sext i32 [[EXT_1]] to i64
; CHECK-NEXT: ret i64 [[EXT_2]]
;
%p = and i16 %x, 15
; CHECK-NEXT: store i32 2, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @x, i64 1, i64 0), align 4
; CHECK-NEXT: ret i1 true
; CHECK: if.end:
-; CHECK-NEXT: [[CMP_2:%.*]] = icmp eq i32* [[P]], getelementptr inbounds ([1 x i32], [1 x i32]* @x, i64 1, i64 0)
-; CHECK-NEXT: ret i1 [[CMP_2]]
+; CHECK-NEXT: ret i1 false
;
entry:
%cmp.0 = icmp eq i32* %p, getelementptr inbounds (i32, i32* getelementptr inbounds ([1 x i32], [1 x i32]* @x, i64 0, i64 0), i64 1)