llvm.org GIT mirror llvm / eb8bc2a
[InstCombine] Don't violate dominance when replacing instructions. Differential Revision: https://reviews.llvm.org/D35376 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308144 91177308-0d34-0410-b5e6-96231b3b80d8 Davide Italiano 3 years ago
3 changed file(s) with 66 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
37483748 const APInt &CVal = CI->getValue();
37493749 if (CVal.getBitWidth() - CVal.countLeadingZeros() > MulWidth)
37503750 return nullptr;
3751 } else {
3752 // In this case we could have the operand of the binary operation
3753 // being defined in another block, and performing the replacement
3754 // could break the dominance relation.
3755 return nullptr;
37513756 }
37523757 } else {
37533758 // Other uses prohibit this transformation.
38673872 } else if (BinaryOperator *BO = dyn_cast(U)) {
38683873 assert(BO->getOpcode() == Instruction::And);
38693874 // Replace (mul & mask) --> zext (mul.with.overflow & short_mask)
3870 Value *ShortMask =
3871 Builder.CreateTrunc(BO->getOperand(1), Builder.getIntNTy(MulWidth));
3875 ConstantInt *CI = cast(BO->getOperand(1));
3876 APInt ShortMask = CI->getValue().trunc(MulWidth);
38723877 Value *ShortAnd = Builder.CreateAnd(Mul, ShortMask);
3873 Value *Zext = Builder.CreateZExt(ShortAnd, BO->getType());
3874 if (auto *ZextI = dyn_cast(Zext))
3875 IC.Worklist.Add(ZextI);
3878 Instruction *Zext =
3879 cast(Builder.CreateZExt(ShortAnd, BO->getType()));
3880 IC.Worklist.Add(Zext);
38763881 IC.replaceInstUsesWith(*BO, Zext);
38773882 } else {
38783883 llvm_unreachable("Unexpected Binary operation");
38793884 }
3880 if (auto *UI = dyn_cast(U))
3881 IC.Worklist.Add(UI);
3885 IC.Worklist.Add(cast(U));
38823886 }
38833887 }
38843888 if (isa(OtherVal))
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt < %s -instcombine -S | FileCheck %s
12
2 ; CHECK: llvm.umul.with.overflow
33 define i32 @sterix(i32, i8, i64) {
4 ; CHECK-LABEL: @sterix(
5 ; CHECK-NEXT: entry:
6 ; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[TMP0:%.*]] to i64
7 ; CHECK-NEXT: [[CONV1:%.*]] = sext i8 [[TMP1:%.*]] to i32
8 ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[CONV1]], 1945964878
9 ; CHECK-NEXT: [[SH_PROM:%.*]] = trunc i64 [[TMP2:%.*]] to i32
10 ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], [[SH_PROM]]
11 ; CHECK-NEXT: [[CONV2:%.*]] = zext i32 [[SHR]] to i64
12 ; CHECK-NEXT: [[MUL3:%.*]] = mul nuw nsw i64 [[CONV]], [[CONV2]]
13 ; CHECK-NEXT: [[CONV6:%.*]] = and i64 [[MUL3]], 4294967295
14 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[CONV6]], [[MUL3]]
15 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]
16 ; CHECK: lor.rhs:
17 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[MUL3]], [[TMP2]]
18 ; CHECK-NEXT: [[CONV4:%.*]] = trunc i64 [[AND]] to i32
19 ; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp eq i32 [[CONV4]], 0
20 ; CHECK-NEXT: [[PHITMP:%.*]] = zext i1 [[TOBOOL7]] to i32
21 ; CHECK-NEXT: br label [[LOR_END]]
22 ; CHECK: lor.end:
23 ; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHITMP]], [[LOR_RHS]] ]
24 ; CHECK-NEXT: ret i32 [[TMP3]]
25 ;
426 entry:
527 %conv = zext i32 %0 to i64
628 %conv1 = sext i8 %1 to i32
0 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1 ; RUN: opt -S %s -instcombine | FileCheck %s
2
3 @glob = external global i16
4
5 define void @patatino(i8 %beth) {
6 ; CHECK-LABEL: @patatino(
7 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[BETH:%.*]] to i32
8 ; CHECK-NEXT: br i1 undef, label [[IF_THEN9:%.*]], label [[IF_THEN9]]
9 ; CHECK: if.then9:
10 ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[CONV]], [[CONV]]
11 ; CHECK-NEXT: [[TINKY:%.*]] = load i16, i16* @glob, align 2
12 ; CHECK-NEXT: [[CONV131:%.*]] = zext i16 [[TINKY]] to i32
13 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[MUL]], [[CONV131]]
14 ; CHECK-NEXT: [[CONV14:%.*]] = trunc i32 [[AND]] to i16
15 ; CHECK-NEXT: store i16 [[CONV14]], i16* @glob, align 2
16 ; CHECK-NEXT: ret void
17 ;
18 %conv = zext i8 %beth to i32
19 %mul = mul nuw nsw i32 %conv, %conv
20 %conv3 = and i32 %mul, 255
21 %tobool8 = icmp ne i32 %mul, %conv3
22 br i1 %tobool8, label %if.then9, label %if.then9
23
24 if.then9:
25 %tinky = load i16, i16* @glob
26 %conv13 = sext i16 %tinky to i32
27 %and = and i32 %mul, %conv13
28 %conv14 = trunc i32 %and to i16
29 store i16 %conv14, i16* @glob
30 ret void
31 }