1 ; RUN: opt -codegenprepare -disable-cgp-branch-opts -S < %s | FileCheck %s 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 ; The first cast should be sunk into block2, in order that the 6 ; instruction selector can form an efficient 7 ; i64 * i64 -> i128 multiplication. 8 define i128 @sink(i64* %mem1, i64* %mem2) { 9 ; CHECK-LABEL: block1: 10 ; CHECK-NEXT: load 11 block1: 12 %l1 = load i64, i64* %mem1 13 %s1 = sext i64 %l1 to i128 14 br label %block2 15 16 ; CHECK-LABEL: block2: 17 ; CHECK-NEXT: sext 18 ; CHECK-NEXT: load 19 ; CHECK-NEXT: sext 20 block2: 21 %l2 = load i64, i64* %mem2 22 %s2 = sext i64 %l2 to i128 23 %res = mul i128 %s1, %s2 24 ret i128 %res 25 } 26 27 ; The first cast should be hoisted into block1, in order that the 28 ; instruction selector can form an extend-load. 29 define i64 @hoist(i32* %mem1, i32* %mem2) { 30 ; CHECK-LABEL: block1: 31 ; CHECK-NEXT: load 32 ; CHECK-NEXT: sext 33 block1: 34 %l1 = load i32, i32* %mem1 35 br label %block2 36 37 ; CHECK-LABEL: block2: 38 ; CHECK-NEXT: load 39 ; CHECK-NEXT: sext 40 block2: 41 %s1 = sext i32 %l1 to i64 42 %l2 = load i32, i32* %mem2 43 %s2 = sext i32 %l2 to i64 44 %res = mul i64 %s1, %s2 45 ret i64 %res 46 } 47 48 ; Make sure the cast sink logic and OptimizeExtUses don't end up in an infinite 49 ; loop. 50 define i128 @use_ext_source() { 51 block1: 52 %v1 = or i64 undef, undef 53 %v2 = zext i64 %v1 to i128 54 br i1 undef, label %block2, label %block3 55 56 block2: 57 %v3 = add i64 %v1, 1 58 %v4 = zext i64 %v3 to i128 59 br label %block3 60 61 block3: 62 %res = phi i128 [ %v2, %block1 ], [ %v4, %block2 ] 63 ret i128 %res 64 } 65