llvm.org GIT mirror llvm / 8bc44fb
[SCCP] Don't violate the lattice invariants We marked values which are 'undef' as constant instead of undefined which violates SCCP's invariants. If we can figure out that a computation results in 'undef', leave it in the undefined state. This fixes PR16052. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257102 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 3 years ago
2 changed file(s) with 68 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
756756 LatticeVal OpSt = getValueState(I.getOperand(0));
757757 if (OpSt.isOverdefined()) // Inherit overdefinedness of operand
758758 markOverdefined(&I);
759 else if (OpSt.isConstant()) // Propagate constant value
760 markConstant(&I, ConstantExpr::getCast(I.getOpcode(),
761 OpSt.getConstant(), I.getType()));
759 else if (OpSt.isConstant()) {
760 Constant *C =
761 ConstantExpr::getCast(I.getOpcode(), OpSt.getConstant(), I.getType());
762 if (isa(C))
763 return;
764 // Propagate constant value
765 markConstant(&I, C);
766 }
762767 }
763768
764769
858863 LatticeVal &IV = ValueState[&I];
859864 if (IV.isOverdefined()) return;
860865
861 if (V1State.isConstant() && V2State.isConstant())
862 return markConstant(IV, &I,
863 ConstantExpr::get(I.getOpcode(), V1State.getConstant(),
864 V2State.getConstant()));
866 if (V1State.isConstant() && V2State.isConstant()) {
867 Constant *C = ConstantExpr::get(I.getOpcode(), V1State.getConstant(),
868 V2State.getConstant());
869 // X op Y -> undef.
870 if (isa(C))
871 return;
872 return markConstant(IV, &I, C);
873 }
865874
866875 // If something is undef, wait for it to resolve.
867876 if (!V1State.isOverdefined() && !V2State.isOverdefined())
916925 LatticeVal &IV = ValueState[&I];
917926 if (IV.isOverdefined()) return;
918927
919 if (V1State.isConstant() && V2State.isConstant())
920 return markConstant(IV, &I, ConstantExpr::getCompare(I.getPredicate(),
921 V1State.getConstant(),
922 V2State.getConstant()));
928 if (V1State.isConstant() && V2State.isConstant()) {
929 Constant *C = ConstantExpr::getCompare(
930 I.getPredicate(), V1State.getConstant(), V2State.getConstant());
931 if (isa(C))
932 return;
933 return markConstant(IV, &I, C);
934 }
923935
924936 // If operands are still undefined, wait for it to resolve.
925937 if (!V1State.isOverdefined() && !V2State.isOverdefined())
10191031
10201032 Constant *Ptr = Operands[0];
10211033 auto Indices = makeArrayRef(Operands.begin() + 1, Operands.end());
1022 markConstant(&I, ConstantExpr::getGetElementPtr(I.getSourceElementType(), Ptr,
1023 Indices));
1034 Constant *C =
1035 ConstantExpr::getGetElementPtr(I.getSourceElementType(), Ptr, Indices);
1036 if (isa(C))
1037 return;
1038 markConstant(&I, C);
10241039 }
10251040
10261041 void SCCPSolver::visitStoreInst(StoreInst &SI) {
10781093 }
10791094
10801095 // Transform load from a constant into a constant if possible.
1081 if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, DL))
1096 if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, DL)) {
1097 if (isa(C))
1098 return;
10821099 return markConstant(IV, &I, C);
1100 }
10831101
10841102 // Otherwise we cannot say for certain what value this load will produce.
10851103 // Bail out.
11211139
11221140 // If we can constant fold this, mark the result of the call as a
11231141 // constant.
1124 if (Constant *C = ConstantFoldCall(F, Operands, TLI))
1142 if (Constant *C = ConstantFoldCall(F, Operands, TLI)) {
1143 // call -> undef.
1144 if (isa(C))
1145 return;
11251146 return markConstant(I, C);
1147 }
11261148 }
11271149
11281150 // Otherwise, we don't know anything about this call, mark it overdefined.
13781400 // X % undef -> undef. No change.
13791401 if (Op1LV.isUndefined()) break;
13801402
1403 // X / 0 -> undef. No change.
1404 // X % 0 -> undef. No change.
1405 if (Op1LV.isConstant() && Op1LV.getConstant()->isZeroValue())
1406 break;
1407
13811408 // undef / X -> 0. X could be maxint.
13821409 // undef % X -> 0. X could be 1.
13831410 markForcedConstant(&I, Constant::getNullValue(ITy));
0 ; RUN: opt < %s -S -ipsccp | FileCheck %s
1
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 define i64 @fn2() {
6 entry:
7 %conv = sext i32 undef to i64
8 %div = sdiv i64 8, %conv
9 %call2 = call i64 @fn1(i64 %div)
10 ret i64 %call2
11 }
12
13 ; CHECK-DAG: define i64 @fn2(
14 ; CHECK: %[[CALL:.*]] = call i64 @fn1(i64 undef)
15
16 define internal i64 @fn1(i64 %p1) {
17 entry:
18 %tobool = icmp ne i64 %p1, 0
19 %cond = select i1 %tobool, i64 %p1, i64 %p1
20 ret i64 %cond
21 }
22
23 ; CHECK-DAG: define internal i64 @fn1(
24 ; CHECK: %[[SEL:.*]] = select i1 undef, i64 undef, i64 undef
25 ; CHECK: ret i64 %[[SEL]]