llvm.org GIT mirror llvm / 62efd3b
Make JumpThreading smart enough to properly thread StrSwitch when it's compiled with clang++. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112198 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 9 years ago
2 changed file(s) with 243 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
321321 if (isa(InVal) || isa(InVal)) {
322322 ConstantInt *CI = dyn_cast(InVal);
323323 Result.push_back(std::make_pair(CI, PN->getIncomingBlock(i)));
324 } else if (LVI) {
325 Constant *CI = LVI->getConstantOnEdge(InVal,
326 PN->getIncomingBlock(i), BB);
327 ConstantInt *CInt = dyn_cast_or_null(CI);
328 if (CInt)
329 Result.push_back(std::make_pair(CInt, PN->getIncomingBlock(i)));
324330 }
325331 }
326332 return !Result.empty();
366372 }
367373 }
368374 return !Result.empty();
375
376 // Try to process a few other binary operator patterns.
377 } else if (isa(I)) {
378
369379 }
370380
371381 // Handle the NOT form of XOR.
382392 Result[i].first =
383393 cast(ConstantExpr::getNot(Result[i].first));
384394 return true;
395 }
396
397 // Try to simplify some other binary operator values.
398 } else if (BinaryOperator *BO = dyn_cast(I)) {
399 // AND or OR of a value with itself is that value.
400 ConstantInt *CI = dyn_cast(BO->getOperand(1));
401 if (CI && (BO->getOpcode() == Instruction::And ||
402 BO->getOpcode() == Instruction::Or)) {
403 SmallVector, 8> LHSVals;
404 ComputeValueKnownInPredecessors(BO->getOperand(0), BB, LHSVals);
405 for (unsigned i = 0, e = LHSVals.size(); i != e; ++i)
406 if (LHSVals[i].first == CI)
407 Result.push_back(std::make_pair(CI, LHSVals[i].second));
408
409 return !Result.empty();
385410 }
386411 }
387412
422447 // If comparing a live-in value against a constant, see if we know the
423448 // live-in value on any predecessors.
424449 if (LVI && isa(Cmp->getOperand(1)) &&
425 Cmp->getType()->isIntegerTy() && // Not vector compare.
426 (!isa(Cmp->getOperand(0)) ||
427 cast(Cmp->getOperand(0))->getParent() != BB)) {
428 Constant *RHSCst = cast(Cmp->getOperand(1));
429
430 for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
431 BasicBlock *P = *PI;
432 // If the value is known by LazyValueInfo to be a constant in a
433 // predecessor, use that information to try to thread this block.
434 LazyValueInfo::Tristate
435 Res = LVI->getPredicateOnEdge(Cmp->getPredicate(), Cmp->getOperand(0),
436 RHSCst, P, BB);
437 if (Res == LazyValueInfo::Unknown)
438 continue;
439
440 Constant *ResC = ConstantInt::get(Cmp->getType(), Res);
441 Result.push_back(std::make_pair(cast(ResC), P));
450 Cmp->getType()->isIntegerTy()) {
451 if (!isa(Cmp->getOperand(0)) ||
452 cast(Cmp->getOperand(0))->getParent() != BB) {
453 Constant *RHSCst = cast(Cmp->getOperand(1));
454
455 for (pred_iterator PI = pred_begin(BB), E = pred_end(BB);PI != E; ++PI){
456 BasicBlock *P = *PI;
457 // If the value is known by LazyValueInfo to be a constant in a
458 // predecessor, use that information to try to thread this block.
459 LazyValueInfo::Tristate Res =
460 LVI->getPredicateOnEdge(Cmp->getPredicate(), Cmp->getOperand(0),
461 RHSCst, P, BB);
462 if (Res == LazyValueInfo::Unknown)
463 continue;
464
465 Constant *ResC = ConstantInt::get(Cmp->getType(), Res);
466 Result.push_back(std::make_pair(cast(ResC), P));
467 }
468
469 return !Result.empty();
442470 }
443
444 return !Result.empty();
445 }
446 }
471
472 // Try to find a constant value for the LHS of an equality comparison,
473 // and evaluate it statically if we can.
474 if (Cmp->getPredicate() == CmpInst::ICMP_EQ ||
475 Cmp->getPredicate() == CmpInst::ICMP_NE) {
476 SmallVector, 8> LHSVals;
477 ComputeValueKnownInPredecessors(I->getOperand(0), BB, LHSVals);
478
479 ConstantInt *True = ConstantInt::getTrue(I->getContext());
480 ConstantInt *False = ConstantInt::getFalse(I->getContext());
481 if (Cmp->getPredicate() == CmpInst::ICMP_NE) std::swap(True, False);
482
483 for (unsigned i = 0, e = LHSVals.size(); i != e; ++i) {
484 if (LHSVals[i].first == Cmp->getOperand(1))
485 Result.push_back(std::make_pair(True, LHSVals[i].second));
486 else
487 Result.push_back(std::make_pair(False, LHSVals[i].second));
488 }
489
490 return !Result.empty();
491 }
492 }
493 }
494
495 if (LVI) {
496 // If all else fails, see if LVI can figure out a constant value for us.
497 Constant *CI = LVI->getConstant(V, BB);
498 ConstantInt *CInt = dyn_cast_or_null(CI);
499 if (CInt) {
500 for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
501 Result.push_back(std::make_pair(CInt, *PI));
502 }
503
504 return !Result.empty();
505 }
506
447507 return false;
448508 }
449509
0 ; RUN: opt -jump-threading -enable-jump-threading-lvi -S < %s | FileCheck %s
1
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
3 target triple = "x86_64-apple-darwin10.0.0"
4
5 %class.StringSwitch = type { i8*, i32, i32, i8 }
6
7 @.str = private constant [4 x i8] c"red\00" ; <[4 x i8]*> [#uses=1]
8 @.str1 = private constant [7 x i8] c"orange\00" ; <[7 x i8]*> [#uses=1]
9 @.str2 = private constant [7 x i8] c"yellow\00" ; <[7 x i8]*> [#uses=1]
10 @.str3 = private constant [6 x i8] c"green\00" ; <[6 x i8]*> [#uses=1]
11 @.str4 = private constant [5 x i8] c"blue\00" ; <[5 x i8]*> [#uses=1]
12 @.str5 = private constant [7 x i8] c"indigo\00" ; <[7 x i8]*> [#uses=1]
13 @.str6 = private constant [7 x i8] c"violet\00" ; <[7 x i8]*> [#uses=1]
14 @.str7 = private constant [12 x i8] c"Color = %d\0A\00" ; <[12 x i8]*> [#uses=1]
15
16 define i32 @main(i32 %argc, i8** nocapture %argv) nounwind ssp {
17 entry:
18 %cmp142 = icmp sgt i32 %argc, 1 ; [#uses=1]
19 br i1 %cmp142, label %bb.nph, label %for.end
20
21 bb.nph: ; preds = %entry
22 %tmp = add i32 %argc, -2 ; [#uses=1]
23 %tmp144 = zext i32 %tmp to i64 ; [#uses=1]
24 %tmp145 = add i64 %tmp144, 1 ; [#uses=1]
25 br label %land.lhs.true.i
26
27 land.lhs.true.i: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134, %bb.nph
28 %retval.0.i.pre161 = phi i32 [ undef, %bb.nph ], [ %retval.0.i.pre, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134 ] ; [#uses=3]
29 %indvar = phi i64 [ 0, %bb.nph ], [ %tmp146, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134 ] ; [#uses=1]
30 %tmp146 = add i64 %indvar, 1 ; [#uses=3]
31 %arrayidx = getelementptr i8** %argv, i64 %tmp146 ; [#uses=1]
32 %tmp6 = load i8** %arrayidx, align 8 ; [#uses=8]
33 %call.i.i = call i64 @strlen(i8* %tmp6) nounwind ; [#uses=1]
34 %conv.i.i = trunc i64 %call.i.i to i32 ; [#uses=6]\
35 ; CHECK: switch i32 %conv.i.i
36 ; CHECK-NOT: if.then.i40
37 ; CHECK: }
38 switch i32 %conv.i.i, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit [
39 i32 3, label %land.lhs.true5.i
40 i32 6, label %land.lhs.true5.i37
41 ]
42
43 land.lhs.true5.i: ; preds = %land.lhs.true.i
44 %call.i = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i8* %tmp6, i64 4) nounwind ; [#uses=1]
45 %cmp9.i = icmp eq i32 %call.i, 0 ; [#uses=1]
46 br i1 %cmp9.i, label %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
47
48 _ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit: ; preds = %land.lhs.true5.i
49 br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
50
51 land.lhs.true5.i37: ; preds = %land.lhs.true.i
52 %call.i35 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8]* @.str1, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; [#uses=1]
53 %cmp9.i36 = icmp eq i32 %call.i35, 0 ; [#uses=1]
54 br i1 %cmp9.i36, label %if.then.i40, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
55
56 if.then.i40: ; preds = %land.lhs.true5.i37
57 br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
58
59 _ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit: ; preds = %if.then.i40, %land.lhs.true5.i37, %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit, %land.lhs.true5.i, %land.lhs.true.i
60 %retval.0.i.pre159 = phi i32 [ 1, %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre161, %land.lhs.true5.i37 ], [ 2, %if.then.i40 ], [ %retval.0.i.pre161, %land.lhs.true5.i ], [ %retval.0.i.pre161, %land.lhs.true.i ] ; [#uses=2]
61 %tmp2.i44 = phi i8 [ 1, %_ZN12StringSwitchI5ColorE4CaseILj4EEERS1_RAT__KcRKS0_.exit ], [ 0, %land.lhs.true5.i37 ], [ 1, %if.then.i40 ], [ 0, %land.lhs.true5.i ], [ 0, %land.lhs.true.i ] ; [#uses=3]
62 %tobool.i46 = icmp eq i8 %tmp2.i44, 0 ; [#uses=1]
63 %cmp.i49 = icmp eq i32 %conv.i.i, 6 ; [#uses=1]
64 %or.cond = and i1 %tobool.i46, %cmp.i49 ; [#uses=1]
65 br i1 %or.cond, label %land.lhs.true5.i55, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
66
67 land.lhs.true5.i55: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
68 %call.i53 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8]* @.str2, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; [#uses=1]
69 %cmp9.i54 = icmp eq i32 %call.i53, 0 ; [#uses=1]
70 br i1 %cmp9.i54, label %if.then.i58, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
71
72 if.then.i58: ; preds = %land.lhs.true5.i55
73 br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
74
75 _ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60: ; preds = %if.then.i58, %land.lhs.true5.i55, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit
76 %retval.0.i.pre158 = phi i32 [ %retval.0.i.pre159, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre159, %land.lhs.true5.i55 ], [ 3, %if.then.i58 ] ; [#uses=2]
77 %tmp2.i63 = phi i8 [ %tmp2.i44, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit ], [ %tmp2.i44, %land.lhs.true5.i55 ], [ 1, %if.then.i58 ] ; [#uses=3]
78 %tmp14.i64 = and i8 %tmp2.i63, 1 ; [#uses=1]
79 %tobool.i65 = icmp eq i8 %tmp14.i64, 0 ; [#uses=1]
80 %cmp.i68 = icmp eq i32 %conv.i.i, 5 ; [#uses=1]
81 %or.cond168 = and i1 %tobool.i65, %cmp.i68 ; [#uses=1]
82 br i1 %or.cond168, label %land.lhs.true5.i74, label %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
83
84 land.lhs.true5.i74: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
85 %call.i72 = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8]* @.str3, i64 0, i64 0), i8* %tmp6, i64 6) nounwind ; [#uses=1]
86 %cmp9.i73 = icmp eq i32 %call.i72, 0 ; [#uses=1]
87 br i1 %cmp9.i73, label %if.then.i77, label %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
88
89 if.then.i77: ; preds = %land.lhs.true5.i74
90 br label %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
91
92 _ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit: ; preds = %if.then.i77, %land.lhs.true5.i74, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60
93 %retval.0.i.pre157 = phi i32 [ %retval.0.i.pre158, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60 ], [ %retval.0.i.pre158, %land.lhs.true5.i74 ], [ 4, %if.then.i77 ] ; [#uses=2]
94 %tmp2.i81 = phi i8 [ %tmp2.i63, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit60 ], [ %tmp2.i63, %land.lhs.true5.i74 ], [ 1, %if.then.i77 ] ; [#uses=3]
95 %tmp14.i82 = and i8 %tmp2.i81, 1 ; [#uses=1]
96 %tobool.i83 = icmp eq i8 %tmp14.i82, 0 ; [#uses=1]
97 %cmp.i86 = icmp eq i32 %conv.i.i, 4 ; [#uses=1]
98 %or.cond169 = and i1 %tobool.i83, %cmp.i86 ; [#uses=1]
99 br i1 %or.cond169, label %land.lhs.true5.i92, label %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
100
101 land.lhs.true5.i92: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
102 %call.i90 = call i32 @memcmp(i8* getelementptr inbounds ([5 x i8]* @.str4, i64 0, i64 0), i8* %tmp6, i64 5) nounwind ; [#uses=1]
103 %cmp9.i91 = icmp eq i32 %call.i90, 0 ; [#uses=1]
104 br i1 %cmp9.i91, label %if.then.i95, label %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
105
106 if.then.i95: ; preds = %land.lhs.true5.i92
107 br label %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
108
109 _ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit: ; preds = %if.then.i95, %land.lhs.true5.i92, %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit
110 %retval.0.i.pre156 = phi i32 [ %retval.0.i.pre157, %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre157, %land.lhs.true5.i92 ], [ 5, %if.then.i95 ] ; [#uses=2]
111 %tmp2.i99 = phi i8 [ %tmp2.i81, %_ZN12StringSwitchI5ColorE4CaseILj6EEERS1_RAT__KcRKS0_.exit ], [ %tmp2.i81, %land.lhs.true5.i92 ], [ 1, %if.then.i95 ] ; [#uses=3]
112 %tmp14.i100 = and i8 %tmp2.i99, 1 ; [#uses=1]
113 %tobool.i101 = icmp eq i8 %tmp14.i100, 0 ; [#uses=1]
114 %cmp.i104 = icmp eq i32 %conv.i.i, 6 ; [#uses=1]
115 %or.cond170 = and i1 %tobool.i101, %cmp.i104 ; [#uses=1]
116 br i1 %or.cond170, label %land.lhs.true5.i110, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
117
118 land.lhs.true5.i110: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
119 %call.i108 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8]* @.str5, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; [#uses=1]
120 %cmp9.i109 = icmp eq i32 %call.i108, 0 ; [#uses=1]
121 br i1 %cmp9.i109, label %if.then.i113, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
122
123 if.then.i113: ; preds = %land.lhs.true5.i110
124 br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
125
126 _ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115: ; preds = %if.then.i113, %land.lhs.true5.i110, %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit
127 %retval.0.i.pre155 = phi i32 [ %retval.0.i.pre156, %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit ], [ %retval.0.i.pre156, %land.lhs.true5.i110 ], [ 6, %if.then.i113 ] ; [#uses=2]
128 %tmp2.i118 = phi i8 [ %tmp2.i99, %_ZN12StringSwitchI5ColorE4CaseILj5EEERS1_RAT__KcRKS0_.exit ], [ %tmp2.i99, %land.lhs.true5.i110 ], [ 1, %if.then.i113 ] ; [#uses=3]
129 %tmp14.i119 = and i8 %tmp2.i118, 1 ; [#uses=1]
130 %tobool.i120 = icmp eq i8 %tmp14.i119, 0 ; [#uses=1]
131 %cmp.i123 = icmp eq i32 %conv.i.i, 6 ; [#uses=1]
132 %or.cond171 = and i1 %tobool.i120, %cmp.i123 ; [#uses=1]
133 br i1 %or.cond171, label %land.lhs.true5.i129, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134
134
135 land.lhs.true5.i129: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
136 %call.i127 = call i32 @memcmp(i8* getelementptr inbounds ([7 x i8]* @.str6, i64 0, i64 0), i8* %tmp6, i64 7) nounwind ; [#uses=1]
137 %cmp9.i128 = icmp eq i32 %call.i127, 0 ; [#uses=1]
138 br i1 %cmp9.i128, label %if.then.i132, label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134
139
140 if.then.i132: ; preds = %land.lhs.true5.i129
141 br label %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134
142
143 _ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134: ; preds = %if.then.i132, %land.lhs.true5.i129, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115
144 %retval.0.i.pre = phi i32 [ %retval.0.i.pre155, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115 ], [ %retval.0.i.pre155, %land.lhs.true5.i129 ], [ 7, %if.then.i132 ] ; [#uses=2]
145 %tmp2.i137 = phi i8 [ %tmp2.i118, %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit115 ], [ %tmp2.i118, %land.lhs.true5.i129 ], [ 1, %if.then.i132 ] ; [#uses=1]
146 %tmp7.i138 = and i8 %tmp2.i137, 1 ; [#uses=1]
147 %tobool.i139 = icmp eq i8 %tmp7.i138, 0 ; [#uses=1]
148 %retval.0.i = select i1 %tobool.i139, i32 0, i32 %retval.0.i.pre ; [#uses=1]
149 %call22 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str7, i64 0, i64 0), i32 %retval.0.i) ; [#uses=0]
150 %exitcond = icmp eq i64 %tmp146, %tmp145 ; [#uses=1]
151 br i1 %exitcond, label %for.end, label %land.lhs.true.i
152
153 for.end: ; preds = %_ZN12StringSwitchI5ColorE4CaseILj7EEERS1_RAT__KcRKS0_.exit134, %entry
154 ret i32 0
155 }
156
157 declare i32 @printf(i8* nocapture, ...) nounwind
158
159 declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) nounwind readonly
160
161 declare i64 @strlen(i8* nocapture) nounwind readonly